diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 000000000000..76090a4dbe3a --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,3 @@ +self-hosted-runner: + labels: + - pulumi-ubuntu-8core diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index fee19915671a..c3f51722f420 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -151,13 +151,13 @@ jobs: OIDC_ARM_CLIENT_ID: ${{ inputs.oidc_arm_client_id }} run: | set -euo pipefail - cd examples && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt + cd examples && go test -v -json -cover -timeout 2h -tags=${{ matrix.language }} -parallel 16 . 2>&1 | tee /tmp/gotest.log | gotestfmt - name: Run short tests if: inputs.short_test run: | set -euo pipefail - cd examples && go test -v -json -count=1 -cover -timeout 15m -short -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt + cd examples && go test -v -json -cover -timeout 15m -short -tags=${{ matrix.language }} -parallel 16 . 2>&1 | tee /tmp/gotest.log | gotestfmt - name: Tar SDK folder if: ${{ matrix.language != 'go' }} @@ -207,16 +207,27 @@ jobs: with: skip_dotnet_and_java: "true" + - name: Install gotestfmt + uses: jaxxstorm/action-install-gh-release@v1.9.0 + with: + tag: v2.4.0 + repo: GoTestTools/gotestfmt + - run: make ensure - name: Prerequisites artifact restore uses: ./.github/actions/prerequisites-artifact-restore - - name: Mark prerequisites as up-to-date - run: make --touch codegen schema provider + # This is essentially just copying files from bin to the provider folder + - name: Prebuild provider prerequisites + run: | + make --touch codegen schema + make provider_prebuild - name: Test Provider Library - run: PROVIDER_TEST_TAGS=all make test_provider + run: | + set -euo pipefail + cd provider && go test -v -json -coverprofile="coverage.txt" -coverpkg=./... -timeout 1h -parallel 16 ./... 2>&1 | tee /tmp/gotest.log | gotestfmt - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 diff --git a/Makefile b/Makefile index a212645fd416..01cca23e209d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ PROJECT := github.com/pulumi/pulumi-azure-native PROVIDER := pulumi-resource-azure-native CODEGEN := pulumi-gen-azure-native -PROVIDER_PKGS := $(shell cd ./provider && go list ./pkg/...) WORKING_DIR := $(shell pwd) # azure-quickstart-templates is generated by arm2pulumi_coverage_report @@ -59,9 +58,8 @@ arm2pulumi: bin/$(LOCAL_ARM2PULUMI_FILENAME) .PHONY: install_provider install_provider: .make/install_provider -.PHONY: provider_prebuild arm2pulumi_prebuild +.PHONY: provider_prebuild provider_prebuild: .make/provider_prebuild -arm2pulumi_prebuild: .make/arm2pulumi_prebuild # We don't include v2 here yet as this is executed on the nightly updates .PHONY: schema generate_schema generate_docs @@ -126,7 +124,7 @@ arm2pulumi_coverage_report: .make/provider_mod_download provider/cmd/$(PROVIDER) PROVIDER_TEST_TAGS ?= unit # Default to unit tests only for quick local feedback .PHONY: test_provider test_provider: .make/provider_mod_download .make/provider_prebuild provider/cmd/$(PROVIDER)/*.go $(PROVIDER_PKG) - cd provider && go test -v --tags=$(PROVIDER_TEST_TAGS) -coverprofile="coverage.txt" -coverpkg=./... $(PROVIDER_PKGS) + cd provider && go test -v --tags=$(PROVIDER_TEST_TAGS) -coverprofile="coverage.txt" -coverpkg=./... ./... .PHONY: lint_provider lint_provider: .make/provider_mod_download provider/cmd/$(PROVIDER)/*.go $(PROVIDER_PKG) @@ -246,7 +244,7 @@ bin/linux-arm64/arm2pulumi: TARGET := linux-arm64 bin/darwin-amd64/arm2pulumi: TARGET := darwin-amd64 bin/darwin-arm64/arm2pulumi: TARGET := darwin-arm64 bin/windows-amd64/arm2pulumi.exe: TARGET := windows-amd64 -bin/%/arm2pulumi bin/%/arm2pulumi.exe: bin/pulumictl .make/provider_mod_download provider/cmd/arm2pulumi/* .make/arm2pulumi_prebuild $(PROVIDER_PKG) +bin/%/arm2pulumi bin/%/arm2pulumi.exe: bin/pulumictl .make/provider_mod_download provider/cmd/arm2pulumi/* .make/provider_prebuild $(PROVIDER_PKG) cd provider && CGO_ENABLED=0 go build -o $(WORKING_DIR)/$@ $(VERSION_FLAGS) $(PROJECT)/v2/provider/cmd/arm2pulumi bin/$(CODEGEN): bin/pulumictl .make/provider_mod_download provider/cmd/$(CODEGEN)/* $(PROVIDER_PKG) @@ -301,14 +299,11 @@ dist/pulumi-azure-native_$(VERSION_GENERIC)_checksums.txt: dist/$(PROVIDER)-v$(P cd provider && go mod download @touch $@ -.make/arm2pulumi_prebuild: bin/schema-full.json bin/metadata-compact.json - cp bin/schema-full.json provider/cmd/arm2pulumi - cp bin/metadata-compact.json provider/cmd/arm2pulumi - @touch $@ - .make/provider_prebuild: bin/schema-full.json bin/metadata-compact.json cp bin/schema-full.json provider/cmd/$(PROVIDER) cp bin/metadata-compact.json provider/cmd/$(PROVIDER) + cp bin/schema-full.json provider/cmd/arm2pulumi + cp bin/metadata-compact.json provider/cmd/arm2pulumi @touch $@ define FAKE_MODULE diff --git a/provider/pkg/gen/__snapshots__/gen_vnet_test.snap b/provider/pkg/gen/__snapshots__/gen_vnet_test.snap index 3c04af0e0722..07b4c8f9d7d6 100755 --- a/provider/pkg/gen/__snapshots__/gen_vnet_test.snap +++ b/provider/pkg/gen/__snapshots__/gen_vnet_test.snap @@ -224768,6 +224768,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:AdminRuleCollection": { APIVersion: "2023-02-01", @@ -225108,6 +225109,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ApplicationGateway": { APIVersion: "2023-02-01", @@ -227650,6 +227652,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ApplicationGatewayPrivateEndpointConnection": { APIVersion: "2023-02-01", @@ -227926,6 +227929,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ApplicationSecurityGroup": { APIVersion: "2023-02-01", @@ -228195,6 +228199,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:AzureFirewall": { APIVersion: "2023-02-01", @@ -229191,6 +229196,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:BastionHost": { APIVersion: "2023-02-01", @@ -229878,6 +229884,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ConfigurationPolicyGroup": { APIVersion: "2023-02-01", @@ -230271,6 +230278,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ConnectionMonitor": { APIVersion: "2023-02-01", @@ -231124,6 +231132,9 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: { + {"properties"}, + }, }, "azure-native:network/v20230201:ConnectivityConfiguration": { APIVersion: "2023-02-01", @@ -231636,6 +231647,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:CustomIPPrefix": { APIVersion: "2023-02-01", @@ -232521,6 +232533,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:DdosCustomPolicy": { APIVersion: "2023-02-01", @@ -232790,6 +232803,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:DdosProtectionPlan": { APIVersion: "2023-02-01", @@ -233117,6 +233131,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:DefaultAdminRule": { APIVersion: "2023-02-01", @@ -233701,6 +233716,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:DscpConfiguration": { APIVersion: "2023-02-01", @@ -234537,6 +234553,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRouteCircuit": { APIVersion: "2023-02-01", @@ -235462,6 +235479,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRouteCircuitAuthorization": { APIVersion: "2023-02-01", @@ -235738,6 +235756,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRouteCircuitConnection": { APIVersion: "2023-02-01", @@ -236180,6 +236199,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRouteCircuitPeering": { APIVersion: "2023-02-01", @@ -237133,6 +237153,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRouteConnection": { APIVersion: "2023-02-01", @@ -237607,6 +237628,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRouteCrossConnectionPeering": { APIVersion: "2023-02-01", @@ -238282,6 +238304,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRouteGateway": { APIVersion: "2023-02-01", @@ -238729,6 +238752,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRoutePort": { APIVersion: "2023-02-01", @@ -239395,6 +239419,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ExpressRoutePortAuthorization": { APIVersion: "2023-02-01", @@ -239651,6 +239676,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:FirewallPolicy": { APIVersion: "2023-02-01", @@ -240497,6 +240523,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:FirewallPolicyRuleCollectionGroup": { APIVersion: "2023-02-01", @@ -240811,6 +240838,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:FlowLog": { APIVersion: "2023-02-01", @@ -241346,6 +241374,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:HubRouteTable": { APIVersion: "2023-02-01", @@ -241776,6 +241805,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:HubVirtualNetworkConnection": { APIVersion: "2023-02-01", @@ -242171,6 +242201,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:InboundNatRule": { APIVersion: "2023-02-01", @@ -242787,6 +242818,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:IpAllocation": { APIVersion: "2023-02-01", @@ -243314,6 +243346,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:IpGroup": { APIVersion: "2023-02-01", @@ -243719,6 +243752,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:LoadBalancer": { APIVersion: "2023-02-01", @@ -244614,6 +244648,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:LoadBalancerBackendAddressPool": { APIVersion: "2023-02-01", @@ -245262,6 +245297,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: true, + RequiredContainers: nil, }, "azure-native:network/v20230201:LocalNetworkGateway": { APIVersion: "2023-02-01", @@ -245691,6 +245727,9 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: { + {"properties"}, + }, }, "azure-native:network/v20230201:ManagementGroupNetworkManagerConnection": { APIVersion: "2023-02-01", @@ -245875,6 +245914,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NatGateway": { APIVersion: "2023-02-01", @@ -246497,6 +246537,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NatRule": { APIVersion: "2023-02-01", @@ -247027,6 +247068,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkGroup": { APIVersion: "2023-02-01", @@ -247263,6 +247305,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkInterface": { APIVersion: "2023-02-01", @@ -248288,6 +248331,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkInterfaceTapConfiguration": { APIVersion: "2023-02-01", @@ -248524,6 +248568,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkManager": { APIVersion: "2023-02-01", @@ -248971,6 +249016,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkProfile": { APIVersion: "2023-02-01", @@ -249357,6 +249403,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkSecurityGroup": { APIVersion: "2023-02-01", @@ -249900,6 +249947,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkVirtualAppliance": { APIVersion: "2023-02-01", @@ -250879,6 +250927,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkVirtualApplianceConnection": { APIVersion: "2023-02-01", @@ -251330,6 +251379,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:NetworkWatcher": { APIVersion: "2023-02-01", @@ -251579,6 +251629,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:P2sVpnGateway": { APIVersion: "2023-02-01", @@ -252164,6 +252215,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:PacketCapture": { APIVersion: "2023-02-01", @@ -252677,6 +252729,9 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: { + {"properties"}, + }, }, "azure-native:network/v20230201:PrivateDnsZoneGroup": { APIVersion: "2023-02-01", @@ -252950,6 +253005,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:PrivateEndpoint": { APIVersion: "2023-02-01", @@ -253748,6 +253804,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:PrivateLinkService": { APIVersion: "2023-02-01", @@ -254489,6 +254546,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:PrivateLinkServicePrivateEndpointConnection": { APIVersion: "2023-02-01", @@ -254785,6 +254843,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:PublicIPAddress": { APIVersion: "2023-02-01", @@ -255790,6 +255849,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:PublicIPPrefix": { APIVersion: "2023-02-01", @@ -256534,6 +256594,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:Route": { APIVersion: "2023-02-01", @@ -256910,6 +256971,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:RouteFilter": { APIVersion: "2023-02-01", @@ -257315,6 +257377,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:RouteFilterRule": { APIVersion: "2023-02-01", @@ -257689,6 +257752,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:RouteMap": { APIVersion: "2023-02-01", @@ -258099,6 +258163,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:RouteTable": { APIVersion: "2023-02-01", @@ -258525,6 +258590,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:RoutingIntent": { APIVersion: "2023-02-01", @@ -258799,6 +258865,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ScopeConnection": { APIVersion: "2023-02-01", @@ -259075,6 +259142,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:SecurityAdminConfiguration": { APIVersion: "2023-02-01", @@ -259389,6 +259457,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:SecurityPartnerProvider": { APIVersion: "2023-02-01", @@ -259738,6 +259807,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:SecurityRule": { APIVersion: "2023-02-01", @@ -260782,6 +260852,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ServiceEndpointPolicy": { APIVersion: "2023-02-01", @@ -261287,6 +261358,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:ServiceEndpointPolicyDefinition": { APIVersion: "2023-02-01", @@ -261661,6 +261733,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:StaticMember": { APIVersion: "2023-02-01", @@ -261923,6 +261996,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:Subnet": { APIVersion: "2023-02-01", @@ -263062,6 +263136,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:SubscriptionNetworkManagerConnection": { APIVersion: "2023-02-01", @@ -263246,6 +263321,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualApplianceSite": { APIVersion: "2023-02-01", @@ -263522,6 +263598,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualHub": { APIVersion: "2023-02-01", @@ -264665,6 +264742,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualHubBgpConnection": { APIVersion: "2023-02-01", @@ -265001,6 +265079,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualHubIpConfiguration": { APIVersion: "2023-02-01", @@ -265357,6 +265436,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualHubRouteTableV2": { APIVersion: "2023-02-01", @@ -265708,6 +265788,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualNetwork": { APIVersion: "2023-02-01", @@ -266610,6 +266691,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualNetworkGateway": { APIVersion: "2023-02-01", @@ -267893,6 +267975,9 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: { + {"properties"}, + }, }, "azure-native:network/v20230201:VirtualNetworkGatewayConnection": { APIVersion: "2023-02-01", @@ -269291,6 +269376,9 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: { + {"properties"}, + }, }, "azure-native:network/v20230201:VirtualNetworkGatewayNatRule": { APIVersion: "2023-02-01", @@ -269743,6 +269831,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualNetworkPeering": { APIVersion: "2023-02-01", @@ -270465,6 +270554,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualNetworkTap": { APIVersion: "2023-02-01", @@ -270893,6 +270983,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualRouter": { APIVersion: "2023-02-01", @@ -271379,6 +271470,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualRouterPeering": { APIVersion: "2023-02-01", @@ -271655,6 +271747,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VirtualWan": { APIVersion: "2023-02-01", @@ -272142,6 +272235,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VpnConnection": { APIVersion: "2023-02-01", @@ -273111,6 +273205,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VpnGateway": { APIVersion: "2023-02-01", @@ -273755,6 +273850,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VpnServerConfiguration": { APIVersion: "2023-02-01", @@ -274904,6 +275000,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:VpnSite": { APIVersion: "2023-02-01", @@ -275551,6 +275648,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:network/v20230201:WebApplicationFirewallPolicy": { APIVersion: "2023-02-01", @@ -276095,6 +276193,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:storage:Blob": { APIVersion: "", @@ -276390,6 +276489,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, "azure-native:storage:StorageAccountStaticWebsite": { APIVersion: "", @@ -276534,6 +276634,7 @@ ReadMethod: "", ReadPath: "", AutoLocationDisabled: false, + RequiredContainers: nil, }, }, Invokes: { diff --git a/provider/pkg/gen/properties.go b/provider/pkg/gen/properties.go index ed9b7aeeefe5..e2d77948fa00 100644 --- a/provider/pkg/gen/properties.go +++ b/provider/pkg/gen/properties.go @@ -37,8 +37,11 @@ type propertyBag struct { properties map[string]resources.AzureAPIProperty requiredSpecs codegen.StringSet requiredProperties codegen.StringSet + requiredContainers RequiredContainers } +type RequiredContainers [][]string + func (m *moduleGenerator) genProperties(resolvedSchema *openapi.Schema, isOutput, isType bool) (*propertyBag, error) { result := newPropertyBag() @@ -102,6 +105,17 @@ func (m *moduleGenerator) genProperties(resolvedSchema *openapi.Schema, isOutput } bag.properties = newProperties + newRequiredContainers := make(RequiredContainers, len(bag.requiredContainers)) + for i, containers := range bag.requiredContainers { + newRequiredContainers[i] = append([]string{name}, containers...) + } + for _, requiredName := range resolvedSchema.Required { + if requiredName == name { + newRequiredContainers = append(newRequiredContainers, []string{name}) + } + } + bag.requiredContainers = newRequiredContainers + result.merge(bag) continue } @@ -335,6 +349,27 @@ func (bag *propertyBag) merge(other *propertyBag) { for key := range other.requiredProperties { bag.requiredProperties.Add(key) } + bag.requiredContainers = mergeRequiredContainers(bag.requiredContainers, other.requiredContainers) +} + +func mergeRequiredContainers(a, b RequiredContainers) RequiredContainers { + if len(a) == 0 && len(b) == 0 { + return nil + } + result := make(RequiredContainers, 0, len(a)+len(b)) + // Index each container by concatenating its elements with a separator. + // This is necessary because we can't compare slices directly. + index := map[string]bool{} + for _, containers := range a { + index[strings.Join(containers, ".")] = true + result = append(result, containers) + } + for _, containers := range b { + if _, ok := index[strings.Join(containers, ".")]; !ok { + result = append(result, containers) + } + } + return result } // forceNew return true if a property with a given name requires a replacement in the resource diff --git a/provider/pkg/gen/requiredContainers.go b/provider/pkg/gen/requiredContainers.go new file mode 100644 index 000000000000..9e59e332e624 --- /dev/null +++ b/provider/pkg/gen/requiredContainers.go @@ -0,0 +1,11 @@ +package gen + +// Some resources which require empty containers to be present in the request body +// aren't listed as required in the specification, so we add them here manually. +func additionalRequiredContainers(resourceTok string) RequiredContainers { + switch resourceTok { + case "azure-native:app:ManagedEnvironment": + return [][]string{{"properties"}} + } + return nil +} diff --git a/provider/pkg/gen/schema.go b/provider/pkg/gen/schema.go index 6ce233406d01..7759ccd58170 100644 --- a/provider/pkg/gen/schema.go +++ b/provider/pkg/gen/schema.go @@ -786,6 +786,8 @@ func (g *packageGenerator) genResourceVariant(apiSpec *openapi.ResourceSpec, res readMethod = "HEAD" } + requiredContainers := mergeRequiredContainers(resourceRequest.requiredContainers, additionalRequiredContainers(resourceTok)) + r := resources.AzureAPIResource{ APIVersion: swagger.Info.Version, Path: resource.Path, @@ -799,6 +801,7 @@ func (g *packageGenerator) genResourceVariant(apiSpec *openapi.ResourceSpec, res ReadMethod: readMethod, ReadPath: readPath, AutoLocationDisabled: resources.AutoLocationDisabled(resource.Path), + RequiredContainers: requiredContainers, } g.metadata.Resources[resourceTok] = r @@ -1330,10 +1333,11 @@ func getPropertyDescription(schema *spec.Schema, context *openapi.ReferenceConte // parameterBag keeps the schema and metadata parameters for a single resource or invocation. type parameterBag struct { - description string - specs map[string]pschema.PropertySpec - parameters []resources.AzureAPIParameter - requiredSpecs codegen.StringSet + description string + specs map[string]pschema.PropertySpec + parameters []resources.AzureAPIParameter + requiredSpecs codegen.StringSet + requiredContainers RequiredContainers } func newParameterBag() *parameterBag { @@ -1350,6 +1354,7 @@ func (bag *parameterBag) merge(other *propertyBag) { for key := range other.requiredSpecs { bag.requiredSpecs.Add(key) } + bag.requiredContainers = mergeRequiredContainers(bag.requiredContainers, other.requiredContainers) } func rawMessage(v interface{}) pschema.RawMessage { diff --git a/provider/pkg/provider/provider.go b/provider/pkg/provider/provider.go index b41fc33e28b7..181dea2a9bb3 100644 --- a/provider/pkg/provider/provider.go +++ b/provider/pkg/provider/provider.go @@ -31,6 +31,7 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" "github.com/pulumi/pulumi-azure-native/v2/provider/pkg/arm2pulumi" + "github.com/pulumi/pulumi-azure-native/v2/provider/pkg/gen" "github.com/pulumi/pulumi-azure-native/v2/provider/pkg/openapi/defaults" "github.com/pulumi/pulumi-azure-native/v2/provider/pkg/resources" "github.com/pulumi/pulumi-azure-native/v2/provider/pkg/version" @@ -309,6 +310,7 @@ func (k *azureNativeProvider) Invoke(ctx context.Context, req *rpc.InvokeRequest id, body, query, err := k.prepareAzureRESTInputs( res.Path, parameters, + nil, args.Mappable(), map[string]interface{}{ "subscriptionId": k.subscriptionID, @@ -861,6 +863,7 @@ func (k *azureNativeProvider) Create(ctx context.Context, req *rpc.CreateRequest id, bodyParams, queryParams, err := k.prepareAzureRESTInputs( res.Path, res.PutParameters, + res.RequiredContainers, inputs.Mappable(), map[string]interface{}{ "subscriptionId": k.subscriptionID, @@ -1195,6 +1198,7 @@ func (k *azureNativeProvider) Update(ctx context.Context, req *rpc.UpdateRequest id, bodyParams, queryParams, err := k.prepareAzureRESTInputs( res.Path, res.PutParameters, + res.RequiredContainers, inputs.Mappable(), map[string]interface{}{ "subscriptionId": k.subscriptionID, @@ -1817,7 +1821,7 @@ func (k *azureNativeProvider) azurePost( return outputs, nil } -func (k *azureNativeProvider) prepareAzureRESTInputs(path string, parameters []resources.AzureAPIParameter, methodInputs, +func (k *azureNativeProvider) prepareAzureRESTInputs(path string, parameters []resources.AzureAPIParameter, requiredContainers gen.RequiredContainers, methodInputs, clientInputs map[string]interface{}) (string, map[string]interface{}, map[string]interface{}, error) { // Schema-driven mapping of inputs into Autorest id/body/query params := map[string]map[string]interface{}{ @@ -1865,6 +1869,22 @@ func (k *azureNativeProvider) prepareAzureRESTInputs(path string, parameters []r break } + // Ensure all required containers are created. + for _, containers := range requiredContainers { + currentContainer := body + for _, containerName := range containers { + innerContainer, ok := currentContainer[containerName] + if !ok { + innerContainer = map[string]interface{}{} + currentContainer[containerName] = innerContainer + } + currentContainer, ok = innerContainer.(map[string]interface{}) + if !ok { + break + } + } + } + return id, body, params["query"], nil } diff --git a/provider/pkg/provider/provider_e2e_test.go b/provider/pkg/provider/provider_e2e_test.go index 03dbae5fa937..c05c46f8f548 100644 --- a/provider/pkg/provider/provider_e2e_test.go +++ b/provider/pkg/provider/provider_e2e_test.go @@ -29,6 +29,10 @@ func TestApi(t *testing.T) { runTestProgram(t, "api") } +func TestRequiredContainers(t *testing.T) { + runTestProgram(t, "required-containers") +} + // runTestProgram runs an example from ./examples/ // Any editDirs are applied in order, and the program is run after each edit. e.g. ./examples/ func runTestProgram(t *testing.T, initialDir string, editDirs ...string) { diff --git a/provider/pkg/provider/test-programs/required-containers/Pulumi.yaml b/provider/pkg/provider/test-programs/required-containers/Pulumi.yaml new file mode 100644 index 000000000000..7c558b993218 --- /dev/null +++ b/provider/pkg/provider/test-programs/required-containers/Pulumi.yaml @@ -0,0 +1,11 @@ +name: managed-environment +runtime: yaml +description: Tests if required containers are created even if no properties are set within them +resources: + rg: + type: azure-native:resources:ResourceGroup + queryPack: + type: azure-native:operationalinsights:QueryPack + properties: + resourceGroupName: ${rg.name} + location: ${rg.location} diff --git a/provider/pkg/resources/resources.go b/provider/pkg/resources/resources.go index 0e83b403ae37..daa04b8dc60a 100644 --- a/provider/pkg/resources/resources.go +++ b/provider/pkg/resources/resources.go @@ -105,6 +105,8 @@ type AzureAPIResource struct { // By default, we populate the `location` property of every resource to the location of its resource // group or the configured value. AutoLocationDisabled can override this default behavior. AutoLocationDisabled bool `json:"autoLocationDisabled,omitempty"` + // Containers within the request body that are required even if no properties are set within it. + RequiredContainers [][]string `json:"requiredContainers,omitempty"` } func (res *AzureAPIResource) LookupProperty(key string) (AzureAPIProperty, bool) {