Repository: Azure/ARO-RP
Pull request #2320 (2022-08-09 20:32:58)

re-implement cloud aware function for e2e test
### Which issue this PR addresses:
Fixes e2e test failures in USGovCloud environments. [#15119913](https://msazure.visualstudio.com/AzureRedHatOpenShift/_boards/board/t/Chainsaw/Stories/?workitem=15119913)
<!--
Please include a link to the ADO work item as well as any GitHub issues.

Usage: `Fixes #<GitHub issue number>`, or `Fixes (paste link of issue)`.
-->
### What this PR does / why we need it:
Fixes a previously hard-coded string that was causing test failures.
<!--
Include a brief summary of what the PR is intended to accomplish and how the PR
does it. (2-3 sentences)
-->

### Test plan for issue:
Run test in USGovCloud environment. Test now re-implements cloud aware logic from controller so confidence is high that it will work correctly.
<!--
How did you test that this PR works?

- Are there unit tests?
- Are there integration/e2e tests?
- If it is not possible to write automated tests, explain why and document how
  to manually test and verify the feature.
-->

### Is there any documentation that needs to be updated for this PR?
N/A
<!--
- If yes and the docs are in GitHub, include doc updates in the PR.
- If yes and the docs are not in GitHub (i.e. ADO wiki), include a link to the
  docs.
- If no, explain why (e.g. "tech debt cleanup, N/A").
-->



Patch:
diff --git a/.sha256sum b/.sha256sum
index e31263b3c..2ed42ff1e 100644
--- a/.sha256sum
+++ b/.sha256sum
@@ -1,4 +1,4 @@
 468fa0da0a50d50640ec57843ad288af343128b39f5bf23e76e4e336580883d4  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2020-04-30/redhatopenshift.json
 c323c84befa5ea11da50a2407050abed6540ea01e796720bc2241604ce80567c  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2021-09-01-preview/redhatopenshift.json
 e4e522e41855de71c0318db31cbd96c8713e7a74e7c81911bb494f0b194b3f43  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-04-01/redhatopenshift.json
-c10c43ce4d2cb6ff0e6e90f195f41980644c23bb1a8751cff50956b59f825a4a  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/redhatopenshift.json
+cd94fd7a7ec5b67cb158d156606c65c203d4c46707aa7b4b7397d0a5188a2798  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/redhatopenshift.json
diff --git a/Makefile b/Makefile
index 95b810a02..d02a13214 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ E2E_FLAGS ?= -test.timeout 180m -test.v -ginkgo.v -ginkgo.noColor
 # fluentbit version must also be updated in RP code, see pkg/util/version/const.go
 FLUENTBIT_VERSION = 1.9.4-1
 FLUENTBIT_IMAGE ?= ${RP_IMAGE_ACR}.azurecr.io/fluentbit:$(FLUENTBIT_VERSION)
-AUTOREST_VERSION = 3.3.2
+AUTOREST_VERSION = 3.6.2
 AUTOREST_IMAGE = "quay.io/openshift-on-azure/autorest:${AUTOREST_VERSION}"
 
 ifneq ($(shell uname -s),Darwin)
@@ -128,7 +128,7 @@ pyenv:
 	python3 -m venv pyenv
 	. pyenv/bin/activate && \
 		pip install -U pip && \
-		pip install autopep8 azdev azure-mgmt-loganalytics==0.2.0 colorama ruamel.yaml wheel && \
+		pip install -r requirements.txt && \
 		azdev setup -r . && \
 		sed -i -e "s|^dev_sources = $(PWD)$$|dev_sources = $(PWD)/python|" ~/.azure/config
 
diff --git a/docs/upstream-differences.md b/docs/upstream-differences.md
index 9ef38a5d6..09e757d1f 100644
--- a/docs/upstream-differences.md
+++ b/docs/upstream-differences.md
@@ -9,6 +9,8 @@ See https://github.com/openshift/installer/compare/release-4.10...jewzaam:releas
 
 ## Installation differences
 
+* ARO does not use Terraform to create clusters, and instead uses ARM templates directly
+
 * ARO persists the install graph in the cluster storage account in a new "aro"
   container / "graph" blob.
 
@@ -38,19 +40,61 @@ See https://github.com/openshift/installer/compare/release-4.10...jewzaam:releas
 
 # Introducing new OCP release into ARO RP
 
+To support a new version of OpenShift on ARO, you will need to reconcile [upstream changes](https://github.com/openshift/installer) with our [forked installer](https://github.com/jewzaam/installer-aro). This will not be a merge, but a cherry-pick of patches we've implemented.
+
 ## Update installer fork
 
 To bring new OCP release branch into ARO installer fork:
 
-1. Check git diff between the target release branch release-X.Y and previous one release-X.Y-1
-   to see if any resources changed and/or architecture changed.
-   These changes might require more modifications on ARO-RP side later on.
-1. Create a new release-X.Y-azure branch in the ARO installer fork from upstream release-X.Y branch.
-1. Cherry-pick all commits from the previous release-X.Y-1-azure branch into the new one & fix conflicts.
-    * While cherry-picking `commit data/assets_vfsdata.go` commit, run `cd ./hack/assets/ && go run ./assets.go`
-    to generate assets and then add them to this commit.
-1. Run `./hack/build.sh` and `./hack/go-test.sh` as part of every commit (`git rebase` with `-x` can help with this).
-    * Fix build and test failures.
+1. Assess and document differences in X.Y and X.Y-1 in upstream
+    ```sh
+    # clone our forked installer
+    git clone https://github.com/jewzaam/installer-aro.git
+    cd installer-aro
+    
+    # add the upstream as a remote source
+    git remote add upstream https://github.com/openshift/installer.git
+    git fetch upstream -a
+    
+    # diff the upstream X.Y with X.Y-1 and search for architecture changes
+    git diff upstream/release-X.Y-1 upstream/release-X.Y
+    
+    # pay particular attention to Terraform files, which may need to be moved into ARO's ARM templates
+    git diff upstream/release-X.Y-1 upstream/release-X.Y */azure/*.tf
+    ```
+2. Create a new X.Y release branch in our forked installer
+    ```sh
+    # create a new release branch in the fork based on the upstream
+    git checkout upstream/release-X.Y
+    git checkout -b release-X.Y-azure
+    ```
+3. If there is a golang version bump in this release, modify `./hack/build.sh` and `./hack/go-test.sh` with the new version, then verify these scripts still work and commit them
+4. Determine the patches you need to cherry-pick, based on the last (Y-1) release
+    ```sh
+    # find commit shas to cherry-pick from last time
+    git checkout release-X.Y-1-azure
+    git log
+    ```
+5. For every commit you need to cherry-pick (in-order), do:
+    ```sh
+    # WARNING: when you reach the commit for `commit data/assets_vfsdata.go`, look ahead
+    git cherry-pick abc123 # may require manually fixing a merge
+    ./hack/build.sh   # fix any failures
+    ./hack/go-test.sh # fix any failures
+    # if you had to manually merge, you can now `git cherry-pick --continue`
+    ```
+    - When cherry-picking the specific patch `commit data/assets_vfsdata.go`, instead run:
+        ```sh
+        git cherry-pick abc123 # may require manually fixing a merge
+        ./hack/build.sh   # fix any failures
+        ./hack/go-test.sh # fix any failures
+        # if you had to manually merge, you can now `git cherry-pick --continue`
+        pushd ./hack/assets && go run ./assets.go && popd
+        ./hack/build.sh   # fix any failures
+        ./hack/go-test.sh # fix any failures
+        git add data/assets_vfsdata.go
+        git commit --amend
+        ```
 
 **Note:** If any changes are required during the process, make sure to amend the relevant patch or create a new one.
 Each commit should be atomic/complete - you should be able to cherry-pick it into the upstream installer and bring
@@ -89,4 +133,4 @@ Once installer fork is ready:
 1. `make discoverycache`.
     * This command requires a running cluster with the new version.
 1. The list of the hard-coded namespaces in `pkg/util/namespace/namespace.go` needs to be updated regularly as every
-   minor version of upstream OCP introduces a new namespace or two.
\ No newline at end of file
+   minor version of upstream OCP introduces a new namespace or two.
diff --git a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/list.go b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/list.go
index f56f8ba06..f83f30e75 100644
--- a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/list.go
+++ b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/list.go
@@ -23,6 +23,7 @@ import (
 
 	"github.com/Azure/go-autorest/autorest"
 	"github.com/Azure/go-autorest/autorest/azure"
+	"github.com/Azure/go-autorest/autorest/validation"
 	"github.com/Azure/go-autorest/tracing"
 )
 
@@ -43,7 +44,9 @@ func NewListClientWithBaseURI(baseURI string, subscriptionID string) ListClient
 }
 
 // Versions the operation returns the installable OpenShift versions as strings.
-func (client ListClient) Versions(ctx context.Context) (result SetObject, err error) {
+// Parameters:
+// location - the name of Azure region.
+func (client ListClient) Versions(ctx context.Context, location string) (result SetObject, err error) {
 	if tracing.IsEnabled() {
 		ctx = tracing.StartSpan(ctx, fqdn+"/ListClient.Versions")
 		defer func() {
@@ -54,7 +57,15 @@ func (client ListClient) Versions(ctx context.Context) (result SetObject, err er
 			tracing.EndSpan(ctx, sc, err)
 		}()
 	}
-	req, err := client.VersionsPreparer(ctx)
+	if err := validation.Validate([]validation.Validation{
+		{TargetValue: client.SubscriptionID,
+			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
+		{TargetValue: location,
+			Constraints: []validation.Constraint{{Target: "location", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
+		return result, validation.NewError("redhatopenshift.ListClient", "Versions", err.Error())
+	}
+
+	req, err := client.VersionsPreparer(ctx, location)
 	if err != nil {
 		err = autorest.NewErrorWithError(err, "redhatopenshift.ListClient", "Versions", nil, "Failure preparing request")
 		return
@@ -77,7 +88,12 @@ func (client ListClient) Versions(ctx context.Context) (result SetObject, err er
 }
 
 // VersionsPreparer prepares the Versions request.
-func (client ListClient) VersionsPreparer(ctx context.Context) (*http.Request, error) {
+func (client ListClient) VersionsPreparer(ctx context.Context, location string) (*http.Request, error) {
+	pathParameters := map[string]interface{}{
+		"location":       autorest.Encode("path", location),
+		"subscriptionId": autorest.Encode("path", client.SubscriptionID),
+	}
+
 	const APIVersion = "2022-09-04"
 	queryParameters := map[string]interface{}{
 		"api-version": APIVersion,
@@ -86,7 +102,7 @@ func (client ListClient) VersionsPreparer(ctx context.Context) (*http.Request, e
 	preparer := autorest.CreatePreparer(
 		autorest.AsGet(),
 		autorest.WithBaseURL(client.BaseURI),
-		autorest.WithPath("/providers/Microsoft.RedHatOpenShift/listinstallversions"),
+		autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.RedHatOpenShift/locations/{location}/listinstallversions", pathParameters),
 		autorest.WithQueryParameters(queryParameters))
 	return preparer.Prepare((&http.Request{}).WithContext(ctx))
 }
@@ -94,7 +110,7 @@ func (client ListClient) VersionsPreparer(ctx context.Context) (*http.Request, e
 // VersionsSender sends the Versions request. The method will close the
 // http.Response Body if it receives an error.
 func (client ListClient) VersionsSender(req *http.Request) (*http.Response, error) {
-	return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
+	return client.Send(req, azure.DoRetryWithRegistration(client.Client))
 }
 
 // VersionsResponder handles the response to the Versions request. The method always
diff --git a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/models.go b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/models.go
index c27b091e4..87de8b37e 100644
--- a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/models.go
+++ b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/models.go
@@ -52,6 +52,8 @@ type AzureEntityResource struct {
 	Name *string `json:"name,omitempty"`
 	// Type - READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts"
 	Type *string `json:"type,omitempty"`
+	// SystemData - READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information.
+	SystemData *SystemData `json:"systemData,omitempty"`
 }
 
 // MarshalJSON is the custom marshaler for AzureEntityResource.
@@ -147,8 +149,6 @@ type OpenShiftCluster struct {
 	autorest.Response `json:"-"`
 	// OpenShiftClusterProperties - The cluster properties.
 	*OpenShiftClusterProperties `json:"properties,omitempty"`
-	// SystemData - READ-ONLY; The system meta data relating to this resource.
-	SystemData *SystemData `json:"systemData,omitempty"`
 	// Tags - Resource tags.
 	Tags map[string]*string `json:"tags"`
 	// Location - The geo-location where the resource lives
@@ -159,6 +159,8 @@ type OpenShiftCluster struct {
 	Name *string `json:"name,omitempty"`
 	// Type - READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts"
 	Type *string `json:"type,omitempty"`
+	// SystemData - READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information.
+	SystemData *SystemData `json:"systemData,omitempty"`
 }
 
 // MarshalJSON is the custom marshaler for OpenShiftCluster.
@@ -194,15 +196,6 @@ func (osc *OpenShiftCluster) UnmarshalJSON(body []byte) error {
 				}
 				osc.OpenShiftClusterProperties = &openShiftClusterProperties
 			}
-		case "systemData":
-			if v != nil {
-				var systemData SystemData
-				err = json.Unmarshal(*v, &systemData)
-				if err != nil {
-					return err
-				}
-				osc.SystemData = &systemData
-			}
 		case "tags":
 			if v != nil {
 				var tags map[string]*string
@@ -248,6 +241,15 @@ func (osc *OpenShiftCluster) UnmarshalJSON(body []byte) error {
 				}
 				osc.Type = &typeVar
 			}
+		case "systemData":
+			if v != nil {
+				var systemData SystemData
+				err = json.Unmarshal(*v, &systemData)
+				if err != nil {
+					return err
+				}
+				osc.SystemData = &systemData
+			}
 		}
 	}
 
@@ -822,8 +824,8 @@ func NewOperationListPage(cur OperationList, getNextPage func(context.Context, O
 	}
 }
 
-// ProxyResource the resource model definition for an Azure Resource Manager proxy resource. It will have
-// everything other than required location and tags
+// ProxyResource the resource model definition for a Azure Resource Manager proxy resource. It will not
+// have tags and a location
 type ProxyResource struct {
 	// ID - READ-ONLY; Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
 	ID *string `json:"id,omitempty"`
@@ -831,6 +833,8 @@ type ProxyResource struct {
 	Name *string `json:"name,omitempty"`
 	// Type - READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts"
 	Type *string `json:"type,omitempty"`
+	// SystemData - READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information.
+	SystemData *SystemData `json:"systemData,omitempty"`
 }
 
 // MarshalJSON is the custom marshaler for ProxyResource.
@@ -847,6 +851,8 @@ type Resource struct {
 	Name *string `json:"name,omitempty"`
 	// Type - READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts"
 	Type *string `json:"type,omitempty"`
+	// SystemData - READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information.
+	SystemData *SystemData `json:"systemData,omitempty"`
 }
 
 // MarshalJSON is the custom marshaler for Resource.
@@ -881,11 +887,12 @@ type SystemData struct {
 	LastModifiedBy *string `json:"lastModifiedBy,omitempty"`
 	// LastModifiedByType - The type of identity that last modified the resource. Possible values include: 'User', 'Application', 'ManagedIdentity', 'Key'
 	LastModifiedByType CreatedByType `json:"lastModifiedByType,omitempty"`
-	// LastModifiedAt - The type of identity that last modified the resource.
+	// LastModifiedAt - The timestamp of resource last modification (UTC)
 	LastModifiedAt *date.Time `json:"lastModifiedAt,omitempty"`
 }
 
 // TrackedResource the resource model definition for an Azure Resource Manager tracked top level resource
+// which has 'tags' and a 'location'
 type TrackedResource struct {
 	// Tags - Resource tags.
 	Tags map[string]*string `json:"tags"`
@@ -897,6 +904,8 @@ type TrackedResource struct {
 	Name *string `json:"name,omitempty"`
 	// Type - READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts"
 	Type *string `json:"type,omitempty"`
+	// SystemData - READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information.
+	SystemData *SystemData `json:"systemData,omitempty"`
 }
 
 // MarshalJSON is the custom marshaler for TrackedResource.
diff --git a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/openshiftclusters.go b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/openshiftclusters.go
index de7a65a9e..63afd78d4 100644
--- a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/openshiftclusters.go
+++ b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/openshiftclusters.go
@@ -65,8 +65,7 @@ func (client OpenShiftClustersClient) CreateOrUpdate(ctx context.Context, resour
 			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
 		{TargetValue: resourceGroupName,
 			Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
+				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
 		return result, validation.NewError("redhatopenshift.OpenShiftClustersClient", "CreateOrUpdate", err.Error())
 	}
 
@@ -98,7 +97,6 @@ func (client OpenShiftClustersClient) CreateOrUpdatePreparer(ctx context.Context
 		"api-version": APIVersion,
 	}
 
-	parameters.SystemData = nil
 	preparer := autorest.CreatePreparer(
 		autorest.AsContentType("application/json; charset=utf-8"),
 		autorest.AsPut(),
@@ -157,8 +155,7 @@ func (client OpenShiftClustersClient) Delete(ctx context.Context, resourceGroupN
 			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
 		{TargetValue: resourceGroupName,
 			Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
+				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
 		return result, validation.NewError("redhatopenshift.OpenShiftClustersClient", "Delete", err.Error())
 	}
 
@@ -245,8 +242,7 @@ func (client OpenShiftClustersClient) Get(ctx context.Context, resourceGroupName
 			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
 		{TargetValue: resourceGroupName,
 			Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
+				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
 		return result, validation.NewError("redhatopenshift.OpenShiftClustersClient", "Get", err.Error())
 	}
 
@@ -331,8 +327,7 @@ func (client OpenShiftClustersClient) ListAdminCredentials(ctx context.Context,
 			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
 		{TargetValue: resourceGroupName,
 			Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
+				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
 		return result, validation.NewError("redhatopenshift.OpenShiftClustersClient", "ListAdminCredentials", err.Error())
 	}
 
@@ -416,8 +411,7 @@ func (client OpenShiftClustersClient) ListByResourceGroup(ctx context.Context, r
 			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
 		{TargetValue: resourceGroupName,
 			Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
+				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
 		return result, validation.NewError("redhatopenshift.OpenShiftClustersClient", "ListByResourceGroup", err.Error())
 	}
 
@@ -543,8 +537,7 @@ func (client OpenShiftClustersClient) ListCredentials(ctx context.Context, resou
 			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
 		{TargetValue: resourceGroupName,
 			Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
+				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
 		return result, validation.NewError("redhatopenshift.OpenShiftClustersClient", "ListCredentials", err.Error())
 	}
 
@@ -749,8 +742,7 @@ func (client OpenShiftClustersClient) Update(ctx context.Context, resourceGroupN
 			Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}},
 		{TargetValue: resourceGroupName,
 			Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
-				{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
+				{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
 		return result, validation.NewError("redhatopenshift.OpenShiftClustersClient", "Update", err.Error())
 	}
 
diff --git a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/operations.go b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/operations.go
index 0ce06243b..532cfb2e7 100644
--- a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/operations.go
+++ b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/operations.go
@@ -42,10 +42,10 @@ func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string) Opera
 	return OperationsClient{NewWithBaseURI(baseURI, subscriptionID)}
 }
 
-// ListMethod the operation returns the RP operations.
-func (client OperationsClient) ListMethod(ctx context.Context) (result OperationListPage, err error) {
+// List the operation returns the RP operations.
+func (client OperationsClient) List(ctx context.Context) (result OperationListPage, err error) {
 	if tracing.IsEnabled() {
-		ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.ListMethod")
+		ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.List")
 		defer func() {
 			sc := -1
 			if result.ol.Response.Response != nil {
@@ -54,23 +54,23 @@ func (client OperationsClient) ListMethod(ctx context.Context) (result Operation
 			tracing.EndSpan(ctx, sc, err)
 		}()
 	}
-	result.fn = client.listMethodNextResults
-	req, err := client.ListMethodPreparer(ctx)
+	result.fn = client.listNextResults
+	req, err := client.ListPreparer(ctx)
 	if err != nil {
-		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "ListMethod", nil, "Failure preparing request")
+		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "List", nil, "Failure preparing request")
 		return
 	}
 
-	resp, err := client.ListMethodSender(req)
+	resp, err := client.ListSender(req)
 	if err != nil {
 		result.ol.Response = autorest.Response{Response: resp}
-		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "ListMethod", resp, "Failure sending request")
+		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "List", resp, "Failure sending request")
 		return
 	}
 
-	result.ol, err = client.ListMethodResponder(resp)
+	result.ol, err = client.ListResponder(resp)
 	if err != nil {
-		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "ListMethod", resp, "Failure responding to request")
+		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "List", resp, "Failure responding to request")
 		return
 	}
 	if result.ol.hasNextLink() && result.ol.IsEmpty() {
@@ -81,8 +81,8 @@ func (client OperationsClient) ListMethod(ctx context.Context) (result Operation
 	return
 }
 
-// ListMethodPreparer prepares the ListMethod request.
-func (client OperationsClient) ListMethodPreparer(ctx context.Context) (*http.Request, error) {
+// ListPreparer prepares the List request.
+func (client OperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) {
 	const APIVersion = "2022-09-04"
 	queryParameters := map[string]interface{}{
 		"api-version": APIVersion,
@@ -96,15 +96,15 @@ func (client OperationsClient) ListMethodPreparer(ctx context.Context) (*http.Re
 	return preparer.Prepare((&http.Request{}).WithContext(ctx))
 }
 
-// ListMethodSender sends the ListMethod request. The method will close the
+// ListSender sends the List request. The method will close the
 // http.Response Body if it receives an error.
-func (client OperationsClient) ListMethodSender(req *http.Request) (*http.Response, error) {
+func (client OperationsClient) ListSender(req *http.Request) (*http.Response, error) {
 	return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
 }
 
-// ListMethodResponder handles the response to the ListMethod request. The method always
+// ListResponder handles the response to the List request. The method always
 // closes the http.Response Body.
-func (client OperationsClient) ListMethodResponder(resp *http.Response) (result OperationList, err error) {
+func (client OperationsClient) ListResponder(resp *http.Response) (result OperationList, err error) {
 	err = autorest.Respond(
 		resp,
 		azure.WithErrorUnlessStatusCode(http.StatusOK),
@@ -114,31 +114,31 @@ func (client OperationsClient) ListMethodResponder(resp *http.Response) (result
 	return
 }
 
-// listMethodNextResults retrieves the next set of results, if any.
-func (client OperationsClient) listMethodNextResults(ctx context.Context, lastResults OperationList) (result OperationList, err error) {
+// listNextResults retrieves the next set of results, if any.
+func (client OperationsClient) listNextResults(ctx context.Context, lastResults OperationList) (result OperationList, err error) {
 	req, err := lastResults.operationListPreparer(ctx)
 	if err != nil {
-		return result, autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "listMethodNextResults", nil, "Failure preparing next results request")
+		return result, autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "listNextResults", nil, "Failure preparing next results request")
 	}
 	if req == nil {
 		return
 	}
-	resp, err := client.ListMethodSender(req)
+	resp, err := client.ListSender(req)
 	if err != nil {
 		result.Response = autorest.Response{Response: resp}
-		return result, autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "listMethodNextResults", resp, "Failure sending next results request")
+		return result, autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "listNextResults", resp, "Failure sending next results request")
 	}
-	result, err = client.ListMethodResponder(resp)
+	result, err = client.ListResponder(resp)
 	if err != nil {
-		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "listMethodNextResults", resp, "Failure responding to next results request")
+		err = autorest.NewErrorWithError(err, "redhatopenshift.OperationsClient", "listNextResults", resp, "Failure responding to next results request")
 	}
 	return
 }
 
-// ListMethodComplete enumerates all values, automatically crossing page boundaries as required.
-func (client OperationsClient) ListMethodComplete(ctx context.Context) (result OperationListIterator, err error) {
+// ListComplete enumerates all values, automatically crossing page boundaries as required.
+func (client OperationsClient) ListComplete(ctx context.Context) (result OperationListIterator, err error) {
 	if tracing.IsEnabled() {
-		ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.ListMethod")
+		ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.List")
 		defer func() {
 			sc := -1
 			if result.Response().Response.Response != nil {
@@ -147,6 +147,6 @@ func (client OperationsClient) ListMethodComplete(ctx context.Context) (result O
 			tracing.EndSpan(ctx, sc, err)
 		}()
 	}
-	result.page, err = client.ListMethod(ctx)
+	result.page, err = client.List(ctx)
 	return
 }
diff --git a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/redhatopenshiftapi/interfaces.go b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/redhatopenshiftapi/interfaces.go
index d0df5de67..a8942b3aa 100644
--- a/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/redhatopenshiftapi/interfaces.go
+++ b/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift/redhatopenshiftapi/interfaces.go
@@ -23,21 +23,21 @@ import (
 	"github.com/Azure/ARO-RP/pkg/client/services/redhatopenshift/mgmt/2022-09-04/redhatopenshift"
 )
 
-// ListClientAPI contains the set of methods on the ListClient type.
-type ListClientAPI interface {
-	Versions(ctx context.Context) (result redhatopenshift.SetObject, err error)
-}
-
-var _ ListClientAPI = (*redhatopenshift.ListClient)(nil)
-
 // OperationsClientAPI contains the set of methods on the OperationsClient type.
 type OperationsClientAPI interface {
-	ListMethod(ctx context.Context) (result redhatopenshift.OperationListPage, err error)
-	ListMethodComplete(ctx context.Context) (result redhatopenshift.OperationListIterator, err error)
+	List(ctx context.Context) (result redhatopenshift.OperationListPage, err error)
+	ListComplete(ctx context.Context) (result redhatopenshift.OperationListIterator, err error)
 }
 
 var _ OperationsClientAPI = (*redhatopenshift.OperationsClient)(nil)
 
+// ListClientAPI contains the set of methods on the ListClient type.
+type ListClientAPI interface {
+	Versions(ctx context.Context, location string) (result redhatopenshift.SetObject, err error)
+}
+
+var _ ListClientAPI = (*redhatopenshift.ListClient)(nil)
+
 // OpenShiftClustersClientAPI contains the set of methods on the OpenShiftClustersClient type.
 type OpenShiftClustersClientAPI interface {
 	CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceName string, parameters redhatopenshift.OpenShiftCluster) (result redhatopenshift.OpenShiftClustersCreateOrUpdateFuture, err error)
diff --git a/pkg/deploy/assets/env-development.json b/pkg/deploy/assets/env-development.json
index cb65b3a4f..42de87e22 100644
--- a/pkg/deploy/assets/env-development.json
+++ b/pkg/deploy/assets/env-development.json
@@ -59,23 +59,16 @@
             "name": "dev-vpn-pip",
             "type": "Microsoft.Network/publicIPAddresses",
             "location": "[resourceGroup().location]",
-            "condition": "[equals(parameters('ciCapacity'), 0)]",
             "apiVersion": "2020-08-01"
         },
         {
             "properties": {
                 "addressSpace": {
                     "addressPrefixes": [
-                        "10.0.0.0/9"
+                        "10.0.0.0/16"
                     ]
                 },
                 "subnets": [
-                    {
-                        "properties": {
-                            "addressPrefix": "10.0.0.0/24"
-                        },
-                        "name": "GatewaySubnet"
-                    },
                     {
                         "properties": {
                             "addressPrefix": "10.0.1.0/24",
@@ -93,13 +86,34 @@
             "location": "[resourceGroup().location]",
             "apiVersion": "2020-08-01"
         },
+        {
+            "properties": {
+                "addressSpace": {
+                    "addressPrefixes": [
+                        "10.2.0.0/24"
+                    ]
+                },
+                "subnets": [
+                    {
+                        "properties": {
+                            "addressPrefix": "10.2.0.0/24"
+                        },
+                        "name": "GatewaySubnet"
+                    }
+                ]
+            },
+            "name": "dev-vpn-vnet",
+            "type": "Microsoft.Network/virtualNetworks",
+            "location": "[resourceGroup().location]",
+            "apiVersion": "2020-08-01"
+        },
         {
             "properties": {
                 "ipConfigurations": [
                     {
                         "properties": {
                             "subnet": {
-                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'dev-vnet', 'GatewaySubnet')]"
+                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'dev-vpn-vnet', 'GatewaySubnet')]"
                             },
                             "publicIPAddress": {
                                 "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'dev-vpn-pip')]"
@@ -135,11 +149,10 @@
             "name": "dev-vpn",
             "type": "Microsoft.Network/virtualNetworkGateways",
             "location": "[resourceGroup().location]",
-            "condition": "[equals(parameters('ciCapacity'), 0)]",
             "apiVersion": "2020-08-01",
             "dependsOn": [
                 "[resourceId('Microsoft.Network/publicIPAddresses', 'dev-vpn-pip')]",
-                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]"
+                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]"
             ]
         },
         {
@@ -407,6 +420,84 @@
             "type": "Microsoft.Compute/virtualMachineScaleSets",
             "location": "[resourceGroup().location]",
             "apiVersion": "2020-12-01"
+        },
+        {
+            "properties": {
+                "allowVirtualNetworkAccess": true,
+                "allowForwardedTraffic": true,
+                "allowGatewayTransit": true,
+                "useRemoteGateways": false,
+                "remoteVirtualNetwork": {
+                    "id": "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]"
+                }
+            },
+            "name": "dev-vpn-vnet/peering-dev-vnet",
+            "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
+            "apiVersion": "2020-08-01",
+            "dependsOn": [
+                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]",
+                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+                "[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]"
+            ],
+            "location": "[resourceGroup().location]"
+        },
+        {
+            "properties": {
+                "allowVirtualNetworkAccess": true,
+                "allowForwardedTraffic": true,
+                "allowGatewayTransit": false,
+                "useRemoteGateways": true,
+                "remoteVirtualNetwork": {
+                    "id": "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]"
+                }
+            },
+            "name": "dev-vnet/peering-dev-vpn-vnet",
+            "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
+            "apiVersion": "2020-08-01",
+            "dependsOn": [
+                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]",
+                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+                "[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]"
+            ],
+            "location": "[resourceGroup().location]"
+        },
+        {
+            "properties": {
+                "allowVirtualNetworkAccess": true,
+                "allowForwardedTraffic": true,
+                "allowGatewayTransit": true,
+                "useRemoteGateways": false,
+                "remoteVirtualNetwork": {
+                    "id": "[resourceId('Microsoft.Network/virtualNetworks', 'rp-vnet')]"
+                }
+            },
+            "name": "dev-vpn-vnet/peering-rp-vnet",
+            "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
+            "apiVersion": "2020-08-01",
+            "dependsOn": [
+                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+                "[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]"
+            ],
+            "location": "[resourceGroup().location]"
+        },
+        {
+            "properties": {
+                "allowVirtualNetworkAccess": true,
+                "allowForwardedTraffic": true,
+                "allowGatewayTransit": false,
+                "useRemoteGateways": true,
+                "remoteVirtualNetwork": {
+                    "id": "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]"
+                }
+            },
+            "name": "rp-vnet/peering-dev-vpn-vnet",
+            "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
+            "apiVersion": "2020-08-01",
+            "dependsOn": [
+                "[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+                "[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]"
+            ],
+            "location": "[resourceGroup().location]"
         }
     ]
 }
diff --git a/pkg/deploy/assets/rp-development-predeploy.json b/pkg/deploy/assets/rp-development-predeploy.json
index b86f887bd..6998cad3c 100644
--- a/pkg/deploy/assets/rp-development-predeploy.json
+++ b/pkg/deploy/assets/rp-development-predeploy.json
@@ -64,13 +64,13 @@
             "properties": {
                 "addressSpace": {
                     "addressPrefixes": [
-                        "10.0.0.0/24"
+                        "10.1.0.0/24"
                     ]
                 },
                 "subnets": [
                     {
                         "properties": {
-                            "addressPrefix": "10.0.0.0/24",
+                            "addressPrefix": "10.1.0.0/24",
                             "networkSecurityGroup": {
                                 "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'rp-nsg')]",
                                 "tags": null
diff --git a/pkg/deploy/assets/rp-production-predeploy.json b/pkg/deploy/assets/rp-production-predeploy.json
index 3d4d10421..378fb78e6 100644
--- a/pkg/deploy/assets/rp-production-predeploy.json
+++ b/pkg/deploy/assets/rp-production-predeploy.json
@@ -195,19 +195,19 @@
                             },
                             "serviceEndpoints": [
                                 {
-                                    "service": "Microsoft.KeyVault",
+                                    "service": "Microsoft.Storage",
                                     "locations": [
                                         "*"
                                     ]
                                 },
                                 {
-                                    "service": "Microsoft.AzureCosmosDB",
+                                    "service": "Microsoft.KeyVault",
                                     "locations": [
                                         "*"
                                     ]
                                 },
                                 {
-                                    "service": "Microsoft.Storage",
+                                    "service": "Microsoft.AzureCosmosDB",
                                     "locations": [
                                         "*"
                                     ]
diff --git a/pkg/deploy/generator/resources.go b/pkg/deploy/generator/resources.go
index 856575924..9ec24b684 100644
--- a/pkg/deploy/generator/resources.go
+++ b/pkg/deploy/generator/resources.go
@@ -113,14 +113,14 @@ func (g *generator) virtualNetwork(name, addressPrefix string, subnets *[]mgmtne
 
 // virtualNetworkPeering configures vnetA to peer with vnetB, two symmetrical
 // configurations have to be applied for a peering to work
-func (g *generator) virtualNetworkPeering(name, vnetB string) *arm.Resource {
+func (g *generator) virtualNetworkPeering(name, vnetB string, allowGatewayTransit, useRemoteGateways bool, dependsOn []string) *arm.Resource {
 	return &arm.Resource{
 		Resource: &mgmtnetwork.VirtualNetworkPeering{
 			VirtualNetworkPeeringPropertiesFormat: &mgmtnetwork.VirtualNetworkPeeringPropertiesFormat{
 				AllowVirtualNetworkAccess: to.BoolPtr(true),
 				AllowForwardedTraffic:     to.BoolPtr(true),
-				AllowGatewayTransit:       to.BoolPtr(false),
-				UseRemoteGateways:         to.BoolPtr(false),
+				AllowGatewayTransit:       to.BoolPtr(allowGatewayTransit),
+				UseRemoteGateways:         to.BoolPtr(useRemoteGateways),
 				RemoteVirtualNetwork: &mgmtnetwork.SubResource{
 					ID: &vnetB,
 				},
@@ -130,6 +130,7 @@ func (g *generator) virtualNetworkPeering(name, vnetB string) *arm.Resource {
 		APIVersion: azureclient.APIVersion("Microsoft.Network"),
 		Type:       "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
 		Location:   "[resourceGroup().location]",
+		DependsOn:  dependsOn,
 	}
 }
 
diff --git a/pkg/deploy/generator/resources_dev.go b/pkg/deploy/generator/resources_dev.go
index ec098331f..96c064e63 100644
--- a/pkg/deploy/generator/resources_dev.go
+++ b/pkg/deploy/generator/resources_dev.go
@@ -212,19 +212,12 @@ func (g *generator) devVPNPip() *arm.Resource {
 			Type:     to.StringPtr("Microsoft.Network/publicIPAddresses"),
 			Location: to.StringPtr("[resourceGroup().location]"),
 		},
-		Condition:  "[equals(parameters('ciCapacity'), 0)]", // TODO(mj): Refactor g.conditionStanza for better usage
 		APIVersion: azureclient.APIVersion("Microsoft.Network"),
 	}
 }
 
 func (g *generator) devVnet() *arm.Resource {
-	return g.virtualNetwork("dev-vnet", "10.0.0.0/9", &[]mgmtnetwork.Subnet{
-		{
-			SubnetPropertiesFormat: &mgmtnetwork.SubnetPropertiesFormat{
-				AddressPrefix: to.StringPtr("10.0.0.0/24"),
-			},
-			Name: to.StringPtr("GatewaySubnet"),
-		},
+	return g.virtualNetwork("dev-vnet", "10.0.0.0/16", &[]mgmtnetwork.Subnet{
 		{
 			SubnetPropertiesFormat: &mgmtnetwork.SubnetPropertiesFormat{
 				AddressPrefix: to.StringPtr("10.0.1.0/24"),
@@ -237,6 +230,17 @@ func (g *generator) devVnet() *arm.Resource {
 	}, nil, nil)
 }
 
+func (g *generator) devVPNVnet() *arm.Resource {
+	return g.virtualNetwork("dev-vpn-vnet", "10.2.0.0/24", &[]mgmtnetwork.Subnet{
+		{
+			SubnetPropertiesFormat: &mgmtnetwork.SubnetPropertiesFormat{
+				AddressPrefix: to.StringPtr("10.2.0.0/24"),
+			},
+			Name: to.StringPtr("GatewaySubnet"),
+		},
+	}, nil, nil)
+}
+
 func (g *generator) devVPN() *arm.Resource {
 	return &arm.Resource{
 		Resource: &mgmtnetwork.VirtualNetworkGateway{
@@ -245,7 +249,7 @@ func (g *generator) devVPN() *arm.Resource {
 					{
 						VirtualNetworkGatewayIPConfigurationPropertiesFormat: &mgmtnetwork.VirtualNetworkGatewayIPConfigurationPropertiesFormat{
 							Subnet: &mgmtnetwork.SubResource{
-								ID: to.StringPtr("[resourceId('Microsoft.Network/virtualNetworks/subnets', 'dev-vnet', 'GatewaySubnet')]"),
+								ID: to.StringPtr("[resourceId('Microsoft.Network/virtualNetworks/subnets', 'dev-vpn-vnet', 'GatewaySubnet')]"),
 							},
 							PublicIPAddress: &mgmtnetwork.SubResource{
 								ID: to.StringPtr("[resourceId('Microsoft.Network/publicIPAddresses', 'dev-vpn-pip')]"),
@@ -280,11 +284,10 @@ func (g *generator) devVPN() *arm.Resource {
 			Type:     to.StringPtr("Microsoft.Network/virtualNetworkGateways"),
 			Location: to.StringPtr("[resourceGroup().location]"),
 		},
-		Condition:  "[equals(parameters('ciCapacity'), 0)]", // TODO(mj): Refactor g.conditionStanza for better usage
 		APIVersion: azureclient.APIVersion("Microsoft.Network"),
 		DependsOn: []string{
 			"[resourceId('Microsoft.Network/publicIPAddresses', 'dev-vpn-pip')]",
-			"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]",
+			"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
 		},
 	}
 }
diff --git a/pkg/deploy/generator/resources_rp.go b/pkg/deploy/generator/resources_rp.go
index c48a0d6db..116643749 100644
--- a/pkg/deploy/generator/resources_rp.go
+++ b/pkg/deploy/generator/resources_rp.go
@@ -136,18 +136,29 @@ func (g *generator) rpPESecurityGroup() *arm.Resource {
 }
 
 func (g *generator) rpVnet() *arm.Resource {
+	addressPrefix := "10.1.0.0/24"
+	if g.production {
+		addressPrefix = "10.0.0.0/24"
+	}
+
 	subnet := mgmtnetwork.Subnet{
 		SubnetPropertiesFormat: &mgmtnetwork.SubnetPropertiesFormat{
-			AddressPrefix: to.StringPtr("10.0.0.0/24"),
+			AddressPrefix: to.StringPtr(addressPrefix),
 			NetworkSecurityGroup: &mgmtnetwork.SecurityGroup{
 				ID: to.StringPtr("[resourceId('Microsoft.Network/networkSecurityGroups', 'rp-nsg')]"),
 			},
+			ServiceEndpoints: &[]mgmtnetwork.ServiceEndpointPropertiesFormat{
+				{
+					Service:   to.StringPtr("Microsoft.Storage"),
+					Locations: &[]string{"*"},
+				},
+			},
 		},
 		Name: to.StringPtr("rp-subnet"),
 	}
 
 	if g.production {
-		subnet.ServiceEndpoints = &[]mgmtnetwork.ServiceEndpointPropertiesFormat{
+		*subnet.ServiceEndpoints = append(*subnet.ServiceEndpoints, []mgmtnetwork.ServiceEndpointPropertiesFormat{
 			{
 				Service:   to.StringPtr("Microsoft.KeyVault"),
 				Locations: &[]string{"*"},
@@ -156,21 +167,10 @@ func (g *generator) rpVnet() *arm.Resource {
 				Service:   to.StringPtr("Microsoft.AzureCosmosDB"),
 				Locations: &[]string{"*"},
 			},
-			{
-				Service:   to.StringPtr("Microsoft.Storage"),
-				Locations: &[]string{"*"},
-			},
-		}
-	} else {
-		subnet.ServiceEndpoints = &[]mgmtnetwork.ServiceEndpointPropertiesFormat{
-			{
-				Service:   to.StringPtr("Microsoft.Storage"),
-				Locations: &[]string{"*"},
-			},
-		}
+		}...)
 	}
 
-	return g.virtualNetwork("rp-vnet", "10.0.0.0/24", &[]mgmtnetwork.Subnet{subnet}, nil, []string{"[resourceId('Microsoft.Network/networkSecurityGroups', 'rp-nsg')]"})
+	return g.virtualNetwork("rp-vnet", addressPrefix, &[]mgmtnetwork.Subnet{subnet}, nil, []string{"[resourceId('Microsoft.Network/networkSecurityGroups', 'rp-nsg')]"})
 }
 
 func (g *generator) rpPEVnet() *arm.Resource {
diff --git a/pkg/deploy/generator/templates_dev.go b/pkg/deploy/generator/templates_dev.go
index bed72cbc6..52f51f683 100644
--- a/pkg/deploy/generator/templates_dev.go
+++ b/pkg/deploy/generator/templates_dev.go
@@ -31,6 +31,7 @@ func (g *generator) devSharedTemplate() *arm.Template {
 	t.Resources = append(t.Resources,
 		g.devVPNPip(),
 		g.devVnet(),
+		g.devVPNVnet(),
 		g.devVPN(),
 		g.devCIPool(),
 		g.devDiskEncryptionKeyvault(),
@@ -39,6 +40,46 @@ func (g *generator) devSharedTemplate() *arm.Template {
 		g.devDiskEncryptionSet(),
 		g.devProxyVMSS())
 
+	t.Resources = append(t.Resources,
+		g.virtualNetworkPeering("dev-vpn-vnet/peering-dev-vnet",
+			"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]",
+			true,
+			false,
+			[]string{
+				"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]",
+				"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+				"[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]",
+			},
+		),
+		g.virtualNetworkPeering("dev-vnet/peering-dev-vpn-vnet",
+			"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+			false,
+			true,
+			[]string{
+				"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vnet')]",
+				"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+				"[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]",
+			},
+		),
+		g.virtualNetworkPeering("dev-vpn-vnet/peering-rp-vnet",
+			"[resourceId('Microsoft.Network/virtualNetworks', 'rp-vnet')]",
+			true,
+			false,
+			[]string{
+				"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+				"[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]",
+			},
+		),
+		g.virtualNetworkPeering("rp-vnet/peering-dev-vpn-vnet",
+			"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+			false,
+			true,
+			[]string{
+				"[resourceId('Microsoft.Network/virtualNetworks', 'dev-vpn-vnet')]",
+				"[resourceId('Microsoft.Network/virtualNetworkGateways', 'dev-vpn')]",
+			},
+		))
+
 	for _, param := range []string{
 		"ciAzpToken",
 		"ciCapacity",
diff --git a/pkg/deploy/generator/templates_gateway.go b/pkg/deploy/generator/templates_gateway.go
index a7e411f01..f234f008d 100644
--- a/pkg/deploy/generator/templates_gateway.go
+++ b/pkg/deploy/generator/templates_gateway.go
@@ -91,7 +91,7 @@ func (g *generator) gatewayTemplate() *arm.Template {
 	)
 
 	t.Resources = append(t.Resources,
-		g.virtualNetworkPeering("gateway-vnet/peering-rp-vnet", "[resourceId(parameters('rpResourceGroupName'), 'Microsoft.Network/virtualNetworks', 'rp-vnet')]"),
+		g.virtualNetworkPeering("gateway-vnet/peering-rp-vnet", "[resourceId(parameters('rpResourceGroupName'), 'Microsoft.Network/virtualNetworks', 'rp-vnet')]", false, false, nil),
 	)
 
 	t.Resources = append(t.Resources, g.gatewayRBAC()...)
diff --git a/pkg/deploy/generator/templates_rp.go b/pkg/deploy/generator/templates_rp.go
index 3239d6f6b..c74d725f3 100644
--- a/pkg/deploy/generator/templates_rp.go
+++ b/pkg/deploy/generator/templates_rp.go
@@ -55,6 +55,7 @@ func (g *generator) rpTemplate() *arm.Template {
 			"gatewayDomains",
 			"gatewayResourceGroupName",
 			"gatewayServicePrincipalId",
+			"ipRules",
 			"mdmFrontendUrl",
 			"mdsdEnvironment",
 			"nonZonalRegions",
@@ -138,13 +139,13 @@ func (g *generator) rpTemplate() *arm.Template {
 		t.Resources = append(t.Resources, g.rpBillingContributorRbac()...)
 
 		t.Resources = append(t.Resources,
-			g.virtualNetworkPeering("rp-vnet/peering-gateway-vnet", "[resourceId(parameters('gatewayResourceGroupName'), 'Microsoft.Network/virtualNetworks', 'gateway-vnet')]"),
+			g.virtualNetworkPeering("rp-vnet/peering-gateway-vnet", "[resourceId(parameters('gatewayResourceGroupName'), 'Microsoft.Network/virtualNetworks', 'gateway-vnet')]", false, false, nil),
 		)
 	}
 
 	t.Resources = append(t.Resources, g.rpDNSZone(),
-		g.virtualNetworkPeering("rp-vnet/peering-rp-pe-vnet-001", "[resourceId('Microsoft.Network/virtualNetworks', 'rp-pe-vnet-001')]"),
-		g.virtualNetworkPeering("rp-pe-vnet-001/peering-rp-vnet", "[resourceId('Microsoft.Network/virtualNetworks', 'rp-vnet')]"))
+		g.virtualNetworkPeering("rp-vnet/peering-rp-pe-vnet-001", "[resourceId('Microsoft.Network/virtualNetworks', 'rp-pe-vnet-001')]", false, false, nil),
+		g.virtualNetworkPeering("rp-pe-vnet-001/peering-rp-vnet", "[resourceId('Microsoft.Network/virtualNetworks', 'rp-vnet')]", false, false, nil))
 	t.Resources = append(t.Resources, g.rpCosmosDB()...)
 	t.Resources = append(t.Resources, g.rpRBAC()...)
 
diff --git a/pkg/frontend/admin_openshiftcluster_kubernetesobjects.go b/pkg/frontend/admin_openshiftcluster_kubernetesobjects.go
index abad145c8..b97cf1ab5 100644
--- a/pkg/frontend/admin_openshiftcluster_kubernetesobjects.go
+++ b/pkg/frontend/admin_openshiftcluster_kubernetesobjects.go
@@ -74,12 +74,20 @@ func (f *frontend) _deleteAdminKubernetesObjects(ctx context.Context, r *http.Re
 	vars := mux.Vars(r)
 
 	groupKind, namespace, name := r.URL.Query().Get("kind"), r.URL.Query().Get("namespace"), r.URL.Query().Get("name")
+	force := strings.EqualFold(r.URL.Query().Get("force"), "true")
 
 	err := validateAdminKubernetesObjectsNonCustomer(r.Method, groupKind, namespace, name)
 	if err != nil {
 		return err
 	}
 
+	if force {
+		err := validateAdminKubernetesObjectsForceDelete(groupKind)
+		if err != nil {
+			return err
+		}
+	}
+
 	resourceID := strings.TrimPrefix(r.URL.Path, "/admin")
 
 	doc, err := f.dbOpenShiftClusters.Get(ctx, resourceID)
@@ -95,7 +103,7 @@ func (f *frontend) _deleteAdminKubernetesObjects(ctx context.Context, r *http.Re
 		return err
 	}
 
-	return k.KubeDelete(ctx, groupKind, namespace, name)
+	return k.KubeDelete(ctx, groupKind, namespace, name, force)
 }
 
 func (f *frontend) postAdminKubernetesObjects(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/frontend/adminactions/kubeactions.go b/pkg/frontend/adminactions/kubeactions.go
index 48511bc03..0180121b9 100644
--- a/pkg/frontend/adminactions/kubeactions.go
+++ b/pkg/frontend/adminactions/kubeactions.go
@@ -7,6 +7,7 @@ import (
 	"context"
 	"net/http"
 
+	"github.com/Azure/go-autorest/autorest/to"
 	configclient "github.com/openshift/client-go/config/clientset/versioned"
 	"github.com/sirupsen/logrus"
 	corev1 "k8s.io/api/core/v1"
@@ -27,7 +28,7 @@ type KubeActions interface {
 	KubeGet(ctx context.Context, groupKind, namespace, name string) ([]byte, error)
 	KubeList(ctx context.Context, groupKind, namespace string) ([]byte, error)
 	KubeCreateOrUpdate(ctx context.Context, obj *unstructured.Unstructured) error
-	KubeDelete(ctx context.Context, groupKind, namespace, name string) error
+	KubeDelete(ctx context.Context, groupKind, namespace, name string, force bool) error
 	CordonNode(ctx context.Context, nodeName string, unschedulable bool) error
 	DrainNode(ctx context.Context, nodeName string) error
 	Upgrade(ctx context.Context, upgradeY bool) error
@@ -140,11 +141,16 @@ func (k *kubeActions) KubeCreateOrUpdate(ctx context.Context, o *unstructured.Un
 	return err
 }
 
-func (k *kubeActions) KubeDelete(ctx context.Context, groupKind, namespace, name string) error {
+func (k *kubeActions) KubeDelete(ctx context.Context, groupKind, namespace, name string, force bool) error {
 	gvr, err := k.gvrResolver.Resolve(groupKind, "")
 	if err != nil {
 		return err
 	}
 
-	return k.dyn.Resource(*gvr).Namespace(namespace).Delete(ctx, name, metav1.DeleteOptions{})
+	resourceDeleteOptions := metav1.DeleteOptions{}
+	if force {
+		resourceDeleteOptions.GracePeriodSeconds = to.Int64Ptr(0)
+	}
+
+	return k.dyn.Resource(*gvr).Namespace(namespace).Delete(ctx, name, resourceDeleteOptions)
 }
diff --git a/pkg/frontend/frontend.go b/pkg/frontend/frontend.go
index 82c0acec6..0dad8a02c 100644
--- a/pkg/frontend/frontend.go
+++ b/pkg/frontend/frontend.go
@@ -218,7 +218,7 @@ func (f *frontend) authenticatedRoutes(r *mux.Router) {
 	s.Methods(http.MethodPost).HandlerFunc(f.postOpenShiftClusterKubeConfigCredentials).Name("postOpenShiftClusterKubeConfigCredentials")
 
 	s = r.
-		Path("/providers/{resourceProviderNamespace}/listinstallversions").
+		Path("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/locations/{location}/listinstallversions").
 		Queries("api-version", "{api-version}").
 		Subrouter()
 
diff --git a/pkg/frontend/operations_get.go b/pkg/frontend/operations_get.go
index b3e731cfc..18fc86633 100644
--- a/pkg/frontend/operations_get.go
+++ b/pkg/frontend/operations_get.go
@@ -91,11 +91,11 @@ func (f *frontend) getOperations(w http.ResponseWriter, r *http.Request) {
 				Origin: "user,system",
 			},
 			{
-				Name: "Microsoft.RedHatOpenShift/listInstallVersions/read",
+				Name: "Microsoft.RedHatOpenShift/locations/listInstallVersions/read",
 				Display: api.Display{
 					Provider:  "Azure Red Hat OpenShift",
 					Resource:  "listInstallVersions",
-					Operation: "Lists all OpenShift versions available to install",
+					Operation: "Lists all OpenShift versions available to install in the specified location",
 				},
 				Origin: "user,system",
 			},
diff --git a/pkg/frontend/validate.go b/pkg/frontend/validate.go
index 363ebf554..334093715 100644
--- a/pkg/frontend/validate.go
+++ b/pkg/frontend/validate.go
@@ -111,6 +111,14 @@ func validateAdminKubernetesObjects(method, groupKind, namespace, name string) e
 	return nil
 }
 
+func validateAdminKubernetesObjectsForceDelete(groupKind string) error {
+	if !strings.EqualFold(groupKind, "Pod") {
+		return api.NewCloudError(http.StatusForbidden, api.CloudErrorCodeForbidden, "", "Force deleting groupKind '%s' is forbidden.", groupKind)
+	}
+
+	return nil
+}
+
 func validateAdminVMName(vmName string) error {
 	if vmName == "" || !rxKubernetesString.MatchString(vmName) {
 		return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, "", "The provided vmName '%s' is invalid.", vmName)
diff --git a/pkg/swagger/generator.go b/pkg/swagger/generator.go
index 45a1e321b..d235cbec6 100644
--- a/pkg/swagger/generator.go
+++ b/pkg/swagger/generator.go
@@ -30,7 +30,7 @@ type generator struct {
 
 	systemData         bool
 	kubeConfig         bool
-	installableVersion bool
+	installVersionList bool
 	xmsEnum            []string
 	xmsSecretList      []string
 	xmsIdentifiers     []string
@@ -93,9 +93,9 @@ var apis = map[string]*generator{
 		xmsEnum:            []string{"EncryptionAtHost", "FipsValidatedModules", "SoftwareDefinedNetwork", "Visibility"},
 		xmsSecretList:      []string{"kubeconfig", "kubeadminPassword"},
 		xmsIdentifiers:     []string{},
-		commonTypesVersion: "v2",
+		commonTypesVersion: "v3",
 		systemData:         true,
-		installableVersion: true,
+		installVersionList: true,
 		kubeConfig:         true,
 	},
 }
diff --git a/pkg/swagger/paths.go b/pkg/swagger/paths.go
index 94f58f37b..ca9558148 100644
--- a/pkg/swagger/paths.go
+++ b/pkg/swagger/paths.go
@@ -17,6 +17,8 @@ import (
 // n==3 action on resource not expecting input payload
 // n==4 action on resource expecting input payload
 // n==5 patch action on resource expecting input payload
+// n==6 list across subscription and location
+
 func (g *generator) populateParameters(n int, typ, friendlyName string) (s []interface{}) {
 	s = []interface{}{
 		Reference{
@@ -28,6 +30,12 @@ func (g *generator) populateParameters(n int, typ, friendlyName string) (s []int
 		s = append(s, Reference{
 			Ref: "../../../../../common-types/resource-management/" + g.commonTypesVersion + "/types.json#/parameters/SubscriptionIdParameter",
 		})
+		if n == 6 {
+			s = append(s, Reference{
+				Ref: "../../../../../common-types/resource-management/" + g.commonTypesVersion + "/types.json#/parameters/LocationParameter",
+			})
+			return
+		}
 	}
 
 	if n > 1 {
diff --git a/pkg/swagger/swagger.go b/pkg/swagger/swagger.go
index 866269cb6..334ca765e 100644
--- a/pkg/swagger/swagger.go
+++ b/pkg/swagger/swagger.go
@@ -89,14 +89,14 @@ func Run(api, outputDir string) error {
 		},
 	}
 
-	if g.installableVersion {
-		s.Paths["/providers/Microsoft.RedHatOpenShift/listinstallversions"] = &PathItem{
+	if g.installVersionList {
+		s.Paths["/subscriptions/{subscriptionId}/providers/Microsoft.RedHatOpenShift/locations/{location}/listinstallversions"] = &PathItem{
 			Get: &Operation{
 				Tags:        []string{"InstallVersions"},
-				Summary:     "Lists all OpenShift versions available to install.",
+				Summary:     "Lists all OpenShift versions available to install in the specified location.",
 				Description: "The operation returns the installable OpenShift versions as strings.",
 				OperationID: "List_Install_Versions",
-				Parameters:  g.populateParameters(0, "InstallVersions", "Install Versions"),
+				Parameters:  g.populateParameters(6, "InstallVersions", "Install Versions"),
 				Responses:   g.populateResponses("InstallVersions", false, http.StatusOK),
 			},
 		}
@@ -108,7 +108,7 @@ func Run(api, outputDir string) error {
 		names = append(names, "OpenShiftClusterAdminKubeconfig")
 	}
 
-	if g.installableVersion {
+	if g.installVersionList {
 		names = append(names, "InstallVersions")
 	}
 
diff --git a/pkg/util/mocks/adminactions/adminactions.go b/pkg/util/mocks/adminactions/adminactions.go
index 28aa65d44..75e0d6514 100644
--- a/pkg/util/mocks/adminactions/adminactions.go
+++ b/pkg/util/mocks/adminactions/adminactions.go
@@ -81,17 +81,17 @@ func (mr *MockKubeActionsMockRecorder) KubeCreateOrUpdate(arg0, arg1 interface{}
 }
 
 // KubeDelete mocks base method.
-func (m *MockKubeActions) KubeDelete(arg0 context.Context, arg1, arg2, arg3 string) error {
+func (m *MockKubeActions) KubeDelete(arg0 context.Context, arg1, arg2, arg3 string, arg4 bool) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "KubeDelete", arg0, arg1, arg2, arg3)
+	ret := m.ctrl.Call(m, "KubeDelete", arg0, arg1, arg2, arg3, arg4)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // KubeDelete indicates an expected call of KubeDelete.
-func (mr *MockKubeActionsMockRecorder) KubeDelete(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+func (mr *MockKubeActionsMockRecorder) KubeDelete(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KubeDelete", reflect.TypeOf((*MockKubeActions)(nil).KubeDelete), arg0, arg1, arg2, arg3)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KubeDelete", reflect.TypeOf((*MockKubeActions)(nil).KubeDelete), arg0, arg1, arg2, arg3, arg4)
 }
 
 // KubeGet mocks base method.
diff --git a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/_azure_red_hat_open_shift_client.py b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/_azure_red_hat_open_shift_client.py
index 1df1b00cf..4e1a0354f 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/_azure_red_hat_open_shift_client.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/_azure_red_hat_open_shift_client.py
@@ -35,10 +35,10 @@ if TYPE_CHECKING:
 class AzureRedHatOpenShiftClient(object):
     """Rest API for Azure Red Hat OpenShift 4.
 
-    :ivar list: ListOperations operations
-    :vartype list: azure.mgmt.redhatopenshift.v2022_09_04.operations.ListOperations
     :ivar operations: Operations operations
     :vartype operations: azure.mgmt.redhatopenshift.v2022_09_04.operations.Operations
+    :ivar list: ListOperations operations
+    :vartype list: azure.mgmt.redhatopenshift.v2022_09_04.operations.ListOperations
     :ivar open_shift_clusters: OpenShiftClustersOperations operations
     :vartype open_shift_clusters:
      azure.mgmt.redhatopenshift.v2022_09_04.operations.OpenShiftClustersOperations
@@ -70,8 +70,8 @@ class AzureRedHatOpenShiftClient(object):
         self._serialize = Serializer(client_models)
         self._deserialize = Deserializer(client_models)
         self._serialize.client_side_validation = False
-        self.list = ListOperations(self._client, self._config, self._serialize, self._deserialize)
         self.operations = Operations(self._client, self._config, self._serialize, self._deserialize)
+        self.list = ListOperations(self._client, self._config, self._serialize, self._deserialize)
         self.open_shift_clusters = OpenShiftClustersOperations(self._client, self._config, self._serialize, self._deserialize)
 
 
diff --git a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models.py b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models.py
index 845a5f1d6..c2f637d92 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models.py
@@ -348,18 +348,23 @@ class Resource(msrest.serialization.Model):
     :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
      "Microsoft.Storage/storageAccounts".
     :vartype type: str
+    :ivar system_data: Azure Resource Manager metadata containing createdBy and modifiedBy
+     information.
+    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     """
 
     _validation = {
         'id': {'readonly': True},
         'name': {'readonly': True},
         'type': {'readonly': True},
+        'system_data': {'readonly': True},
     }
 
     _attribute_map = {
         'id': {'key': 'id', 'type': 'str'},
         'name': {'key': 'name', 'type': 'str'},
         'type': {'key': 'type', 'type': 'str'},
+        'system_data': {'key': 'systemData', 'type': 'SystemData'},
     }
 
     def __init__(
@@ -372,10 +377,11 @@ class Resource(msrest.serialization.Model):
         self.id = None
         self.name = None
         self.type = None
+        self.system_data = None
 
 
 class TrackedResource(Resource):
-    """The resource model definition for an Azure Resource Manager tracked top level resource.
+    """The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'.
 
     Variables are only populated by the server, and will be ignored when sending a request.
 
@@ -389,6 +395,9 @@ class TrackedResource(Resource):
     :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
      "Microsoft.Storage/storageAccounts".
     :vartype type: str
+    :ivar system_data: Azure Resource Manager metadata containing createdBy and modifiedBy
+     information.
+    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     :ivar tags: A set of tags. Resource tags.
     :vartype tags: dict[str, str]
     :ivar location: Required. The geo-location where the resource lives.
@@ -399,6 +408,7 @@ class TrackedResource(Resource):
         'id': {'readonly': True},
         'name': {'readonly': True},
         'type': {'readonly': True},
+        'system_data': {'readonly': True},
         'location': {'required': True},
     }
 
@@ -406,6 +416,7 @@ class TrackedResource(Resource):
         'id': {'key': 'id', 'type': 'str'},
         'name': {'key': 'name', 'type': 'str'},
         'type': {'key': 'type', 'type': 'str'},
+        'system_data': {'key': 'systemData', 'type': 'SystemData'},
         'tags': {'key': 'tags', 'type': '{str}'},
         'location': {'key': 'location', 'type': 'str'},
     }
@@ -440,12 +451,13 @@ class OpenShiftCluster(TrackedResource):
     :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
      "Microsoft.Storage/storageAccounts".
     :vartype type: str
+    :ivar system_data: Azure Resource Manager metadata containing createdBy and modifiedBy
+     information.
+    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     :ivar tags: A set of tags. Resource tags.
     :vartype tags: dict[str, str]
     :ivar location: Required. The geo-location where the resource lives.
     :vartype location: str
-    :ivar system_data: The system meta data relating to this resource.
-    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     :ivar provisioning_state: The cluster provisioning state. Possible values include:
      "AdminUpdating", "Creating", "Deleting", "Failed", "Succeeded", "Updating".
     :vartype provisioning_state: str or
@@ -473,17 +485,17 @@ class OpenShiftCluster(TrackedResource):
         'id': {'readonly': True},
         'name': {'readonly': True},
         'type': {'readonly': True},
-        'location': {'required': True},
         'system_data': {'readonly': True},
+        'location': {'required': True},
     }
 
     _attribute_map = {
         'id': {'key': 'id', 'type': 'str'},
         'name': {'key': 'name', 'type': 'str'},
         'type': {'key': 'type', 'type': 'str'},
+        'system_data': {'key': 'systemData', 'type': 'SystemData'},
         'tags': {'key': 'tags', 'type': '{str}'},
         'location': {'key': 'location', 'type': 'str'},
-        'system_data': {'key': 'systemData', 'type': 'SystemData'},
         'provisioning_state': {'key': 'properties.provisioningState', 'type': 'str'},
         'cluster_profile': {'key': 'properties.clusterProfile', 'type': 'ClusterProfile'},
         'console_profile': {'key': 'properties.consoleProfile', 'type': 'ConsoleProfile'},
@@ -528,7 +540,6 @@ class OpenShiftCluster(TrackedResource):
          list[~azure.mgmt.redhatopenshift.v2022_09_04.models.IngressProfile]
         """
         super(OpenShiftCluster, self).__init__(**kwargs)
-        self.system_data = None
         self.provisioning_state = kwargs.get('provisioning_state', None)
         self.cluster_profile = kwargs.get('cluster_profile', None)
         self.console_profile = kwargs.get('console_profile', None)
@@ -832,7 +843,7 @@ class SystemData(msrest.serialization.Model):
      values include: "User", "Application", "ManagedIdentity", "Key".
     :vartype last_modified_by_type: str or
      ~azure.mgmt.redhatopenshift.v2022_09_04.models.CreatedByType
-    :ivar last_modified_at: The type of identity that last modified the resource.
+    :ivar last_modified_at: The timestamp of resource last modification (UTC).
     :vartype last_modified_at: ~datetime.datetime
     """
 
@@ -863,7 +874,7 @@ class SystemData(msrest.serialization.Model):
          values include: "User", "Application", "ManagedIdentity", "Key".
         :paramtype last_modified_by_type: str or
          ~azure.mgmt.redhatopenshift.v2022_09_04.models.CreatedByType
-        :keyword last_modified_at: The type of identity that last modified the resource.
+        :keyword last_modified_at: The timestamp of resource last modification (UTC).
         :paramtype last_modified_at: ~datetime.datetime
         """
         super(SystemData, self).__init__(**kwargs)
diff --git a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models_py3.py b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models_py3.py
index 735567dc5..92311e601 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models_py3.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/models/_models_py3.py
@@ -388,18 +388,23 @@ class Resource(msrest.serialization.Model):
     :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
      "Microsoft.Storage/storageAccounts".
     :vartype type: str
+    :ivar system_data: Azure Resource Manager metadata containing createdBy and modifiedBy
+     information.
+    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     """
 
     _validation = {
         'id': {'readonly': True},
         'name': {'readonly': True},
         'type': {'readonly': True},
+        'system_data': {'readonly': True},
     }
 
     _attribute_map = {
         'id': {'key': 'id', 'type': 'str'},
         'name': {'key': 'name', 'type': 'str'},
         'type': {'key': 'type', 'type': 'str'},
+        'system_data': {'key': 'systemData', 'type': 'SystemData'},
     }
 
     def __init__(
@@ -412,10 +417,11 @@ class Resource(msrest.serialization.Model):
         self.id = None
         self.name = None
         self.type = None
+        self.system_data = None
 
 
 class TrackedResource(Resource):
-    """The resource model definition for an Azure Resource Manager tracked top level resource.
+    """The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'.
 
     Variables are only populated by the server, and will be ignored when sending a request.
 
@@ -429,6 +435,9 @@ class TrackedResource(Resource):
     :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
      "Microsoft.Storage/storageAccounts".
     :vartype type: str
+    :ivar system_data: Azure Resource Manager metadata containing createdBy and modifiedBy
+     information.
+    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     :ivar tags: A set of tags. Resource tags.
     :vartype tags: dict[str, str]
     :ivar location: Required. The geo-location where the resource lives.
@@ -439,6 +448,7 @@ class TrackedResource(Resource):
         'id': {'readonly': True},
         'name': {'readonly': True},
         'type': {'readonly': True},
+        'system_data': {'readonly': True},
         'location': {'required': True},
     }
 
@@ -446,6 +456,7 @@ class TrackedResource(Resource):
         'id': {'key': 'id', 'type': 'str'},
         'name': {'key': 'name', 'type': 'str'},
         'type': {'key': 'type', 'type': 'str'},
+        'system_data': {'key': 'systemData', 'type': 'SystemData'},
         'tags': {'key': 'tags', 'type': '{str}'},
         'location': {'key': 'location', 'type': 'str'},
     }
@@ -483,12 +494,13 @@ class OpenShiftCluster(TrackedResource):
     :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
      "Microsoft.Storage/storageAccounts".
     :vartype type: str
+    :ivar system_data: Azure Resource Manager metadata containing createdBy and modifiedBy
+     information.
+    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     :ivar tags: A set of tags. Resource tags.
     :vartype tags: dict[str, str]
     :ivar location: Required. The geo-location where the resource lives.
     :vartype location: str
-    :ivar system_data: The system meta data relating to this resource.
-    :vartype system_data: ~azure.mgmt.redhatopenshift.v2022_09_04.models.SystemData
     :ivar provisioning_state: The cluster provisioning state. Possible values include:
      "AdminUpdating", "Creating", "Deleting", "Failed", "Succeeded", "Updating".
     :vartype provisioning_state: str or
@@ -516,17 +528,17 @@ class OpenShiftCluster(TrackedResource):
         'id': {'readonly': True},
         'name': {'readonly': True},
         'type': {'readonly': True},
-        'location': {'required': True},
         'system_data': {'readonly': True},
+        'location': {'required': True},
     }
 
     _attribute_map = {
         'id': {'key': 'id', 'type': 'str'},
         'name': {'key': 'name', 'type': 'str'},
         'type': {'key': 'type', 'type': 'str'},
+        'system_data': {'key': 'systemData', 'type': 'SystemData'},
         'tags': {'key': 'tags', 'type': '{str}'},
         'location': {'key': 'location', 'type': 'str'},
-        'system_data': {'key': 'systemData', 'type': 'SystemData'},
         'provisioning_state': {'key': 'properties.provisioningState', 'type': 'str'},
         'cluster_profile': {'key': 'properties.clusterProfile', 'type': 'ClusterProfile'},
         'console_profile': {'key': 'properties.consoleProfile', 'type': 'ConsoleProfile'},
@@ -583,7 +595,6 @@ class OpenShiftCluster(TrackedResource):
          list[~azure.mgmt.redhatopenshift.v2022_09_04.models.IngressProfile]
         """
         super(OpenShiftCluster, self).__init__(tags=tags, location=location, **kwargs)
-        self.system_data = None
         self.provisioning_state = provisioning_state
         self.cluster_profile = cluster_profile
         self.console_profile = console_profile
@@ -917,7 +928,7 @@ class SystemData(msrest.serialization.Model):
      values include: "User", "Application", "ManagedIdentity", "Key".
     :vartype last_modified_by_type: str or
      ~azure.mgmt.redhatopenshift.v2022_09_04.models.CreatedByType
-    :ivar last_modified_at: The type of identity that last modified the resource.
+    :ivar last_modified_at: The timestamp of resource last modification (UTC).
     :vartype last_modified_at: ~datetime.datetime
     """
 
@@ -955,7 +966,7 @@ class SystemData(msrest.serialization.Model):
          values include: "User", "Application", "ManagedIdentity", "Key".
         :paramtype last_modified_by_type: str or
          ~azure.mgmt.redhatopenshift.v2022_09_04.models.CreatedByType
-        :keyword last_modified_at: The type of identity that last modified the resource.
+        :keyword last_modified_at: The timestamp of resource last modification (UTC).
         :paramtype last_modified_at: ~datetime.datetime
         """
         super(SystemData, self).__init__(**kwargs)
diff --git a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/__init__.py b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/__init__.py
index f5f6ea746..aa3c32929 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/__init__.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/__init__.py
@@ -14,12 +14,12 @@
 # Code generated by Microsoft (R) AutoRest Code Generator.Changes may cause incorrect behavior and will be lost if the code is regenerated.
 # --------------------------------------------------------------------------
 
-from ._list_operations import ListOperations
 from ._operations import Operations
+from ._list_operations import ListOperations
 from ._open_shift_clusters_operations import OpenShiftClustersOperations
 
 __all__ = [
-    'ListOperations',
     'Operations',
+    'ListOperations',
     'OpenShiftClustersOperations',
 ]
diff --git a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_list_operations.py b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_list_operations.py
index 1c9d1bb08..b162f57bb 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_list_operations.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_list_operations.py
@@ -26,7 +26,7 @@ from azure.core.tracing.decorator import distributed_trace
 from azure.mgmt.core.exceptions import ARMErrorFormat
 
 from .. import models as _models
-from .._vendor import _convert_request
+from .._vendor import _convert_request, _format_url_section
 
 if TYPE_CHECKING:
     # pylint: disable=unused-import,ungrouped-imports
@@ -39,6 +39,8 @@ _SERIALIZER.client_side_validation = False
 # fmt: off
 
 def build_install_versions_request(
+    subscription_id,  # type: str
+    location,  # type: str
     **kwargs  # type: Any
 ):
     # type: (...) -> HttpRequest
@@ -46,7 +48,13 @@ def build_install_versions_request(
 
     accept = "application/json"
     # Construct URL
-    _url = kwargs.pop("template_url", "/providers/Microsoft.RedHatOpenShift/listinstallversions")
+    _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/providers/Microsoft.RedHatOpenShift/locations/{location}/listinstallversions")  # pylint: disable=line-too-long
+    path_format_arguments = {
+        "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
+        "location": _SERIALIZER.url("location", location, 'str', min_length=1),
+    }
+
+    _url = _format_url_section(_url, **path_format_arguments)
 
     # Construct parameters
     _query_parameters = kwargs.pop("params", {})  # type: Dict[str, Any]
@@ -90,13 +98,16 @@ class ListOperations(object):
     @distributed_trace
     def install_versions(
         self,
+        location,  # type: str
         **kwargs  # type: Any
     ):
         # type: (...) -> Any
-        """Lists all OpenShift versions available to install.
+        """Lists all OpenShift versions available to install in the specified location.
 
         The operation returns the installable OpenShift versions as strings.
 
+        :param location: The name of Azure region.
+        :type location: str
         :keyword callable cls: A custom type or function that will be passed the direct response
         :return: any, or the result of cls(response)
         :rtype: any
@@ -112,6 +123,8 @@ class ListOperations(object):
 
         
         request = build_install_versions_request(
+            subscription_id=self._config.subscription_id,
+            location=location,
             api_version=api_version,
             template_url=self.install_versions.metadata['url'],
         )
@@ -136,5 +149,5 @@ class ListOperations(object):
 
         return deserialized
 
-    install_versions.metadata = {'url': "/providers/Microsoft.RedHatOpenShift/listinstallversions"}  # type: ignore
+    install_versions.metadata = {'url': "/subscriptions/{subscriptionId}/providers/Microsoft.RedHatOpenShift/locations/{location}/listinstallversions"}  # type: ignore
 
diff --git a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_open_shift_clusters_operations.py b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_open_shift_clusters_operations.py
index 13e7667d6..3c4e93221 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_open_shift_clusters_operations.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2022_09_04/operations/_open_shift_clusters_operations.py
@@ -87,7 +87,7 @@ def build_list_by_resource_group_request(
     _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters")  # pylint: disable=line-too-long
     path_format_arguments = {
         "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
-        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'),
+        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1),
     }
 
     _url = _format_url_section(_url, **path_format_arguments)
@@ -123,7 +123,7 @@ def build_get_request(
     _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters/{resourceName}")  # pylint: disable=line-too-long
     path_format_arguments = {
         "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
-        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'),
+        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1),
         "resourceName": _SERIALIZER.url("resource_name", resource_name, 'str'),
     }
 
@@ -161,7 +161,7 @@ def build_create_or_update_request_initial(
     _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters/{resourceName}")  # pylint: disable=line-too-long
     path_format_arguments = {
         "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
-        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'),
+        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1),
         "resourceName": _SERIALIZER.url("resource_name", resource_name, 'str'),
     }
 
@@ -200,7 +200,7 @@ def build_delete_request_initial(
     _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters/{resourceName}")  # pylint: disable=line-too-long
     path_format_arguments = {
         "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
-        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'),
+        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1),
         "resourceName": _SERIALIZER.url("resource_name", resource_name, 'str'),
     }
 
@@ -238,7 +238,7 @@ def build_update_request_initial(
     _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters/{resourceName}")  # pylint: disable=line-too-long
     path_format_arguments = {
         "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
-        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'),
+        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1),
         "resourceName": _SERIALIZER.url("resource_name", resource_name, 'str'),
     }
 
@@ -277,7 +277,7 @@ def build_list_admin_credentials_request(
     _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters/{resourceName}/listAdminCredentials")  # pylint: disable=line-too-long
     path_format_arguments = {
         "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
-        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'),
+        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1),
         "resourceName": _SERIALIZER.url("resource_name", resource_name, 'str'),
     }
 
@@ -314,7 +314,7 @@ def build_list_credentials_request(
     _url = kwargs.pop("template_url", "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RedHatOpenShift/openShiftClusters/{resourceName}/listCredentials")  # pylint: disable=line-too-long
     path_format_arguments = {
         "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, 'str', min_length=1),
-        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'),
+        "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1),
         "resourceName": _SERIALIZER.url("resource_name", resource_name, 'str'),
     }
 
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 000000000..35bed2595
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+autopep8==1.6.0
+azdev==0.1.37
+azure-mgmt-loganalytics==0.2.0
+colorama==0.4.5
+ruamel.yaml==0.17.21
diff --git a/swagger/common-types/resource-management/v3/types.json b/swagger/common-types/resource-management/v3/types.json
new file mode 100644
index 000000000..3785f8b34
--- /dev/null
+++ b/swagger/common-types/resource-management/v3/types.json
@@ -0,0 +1,695 @@
+{
+  "swagger": "2.0",
+  "info": {
+    "version": "3.0",
+    "title": "Common types"
+  },
+  "paths": {},
+  "definitions": {
+    "Resource": {
+      "title": "Resource",
+      "description": "Common fields that are returned in the response for all Azure Resource Manager resources",
+      "type": "object",
+      "properties": {
+        "id": {
+          "readOnly": true,
+          "type": "string",
+          "description": "Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}"
+        },
+        "name": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The name of the resource"
+        },
+        "type": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The type of the resource. E.g. \"Microsoft.Compute/virtualMachines\" or \"Microsoft.Storage/storageAccounts\""
+        },
+        "systemData": {
+          "readOnly": true,
+          "type": "object",
+          "description": "Azure Resource Manager metadata containing createdBy and modifiedBy information.",
+          "$ref": "#/definitions/systemData"
+        }
+      },
+      "x-ms-azure-resource": true
+    },
+    "AzureEntityResource": {
+      "x-ms-client-name": "AzureEntityResource",
+      "title": "Entity Resource",
+      "description": "The resource model definition for an Azure Resource Manager resource with an etag.",
+      "type": "object",
+      "properties": {
+        "etag": {
+          "type": "string",
+          "readOnly": true,
+          "description": "Resource Etag."
+        }
+      },
+      "allOf": [
+        {
+          "$ref": "#/definitions/Resource"
+        }
+      ]
+    },
+    "TrackedResource": {
+      "title": "Tracked Resource",
+      "description": "The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'",
+      "type": "object",
+      "properties": {
+        "tags": {
+          "type": "object",
+          "additionalProperties": {
+            "type": "string"
+          },
+          "x-ms-mutability": [
+            "read",
+            "create",
+            "update"
+          ],
+          "description": "Resource tags."
+        },
+        "location": {
+          "type": "string",
+          "x-ms-mutability": [
+            "read",
+            "create"
+          ],
+          "description": "The geo-location where the resource lives"
+        }
+      },
+      "required": [
+        "location"
+      ],
+      "allOf": [
+        {
+          "$ref": "#/definitions/Resource"
+        }
+      ]
+    },
+    "ProxyResource": {
+      "title": "Proxy Resource",
+      "description": "The resource model definition for a Azure Resource Manager proxy resource. It will not have tags and a location",
+      "type": "object",
+      "allOf": [
+        {
+          "$ref": "#/definitions/Resource"
+        }
+      ]
+    },
+    "ResourceModelWithAllowedPropertySet": {
+      "description": "The resource model definition containing the full set of allowed properties for a resource. Except properties bag, there cannot be a top level property outside of this set.",
+      "type": "object",
+      "properties": {
+        "id": {
+          "readOnly": true,
+          "type": "string",
+          "x-ms-mutability": [
+            "read"
+          ],
+          "description": "Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}"
+        },
+        "name": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The name of the resource"
+        },
+        "type": {
+          "readOnly": true,
+          "type": "string",
+          "x-ms-mutability": [
+            "read"
+          ],
+          "description": "The type of the resource. E.g. \"Microsoft.Compute/virtualMachines\" or \"Microsoft.Storage/storageAccounts\""
+        },
+        "location": {
+          "type": "string",
+          "x-ms-mutability": [
+            "read",
+            "create"
+          ],
+          "description": "The geo-location where the resource lives"
+        },
+        "managedBy": {
+          "type": "string",
+          "x-ms-mutability": [
+            "read",
+            "create",
+            "update"
+          ],
+          "description": "The fully qualified resource ID of the resource that manages this resource. Indicates if this resource is managed by another Azure resource. If this is present, complete mode deployment will not delete the resource if it is removed from the template since it is managed by another resource."
+        },
+        "kind": {
+          "type": "string",
+          "x-ms-mutability": [
+            "read",
+            "create"
+          ],
+          "description": "Metadata used by portal/tooling/etc to render different UX experiences for resources of the same type; e.g. ApiApps are a kind of Microsoft.Web/sites type.  If supported, the resource provider must validate and persist this value.",
+          "pattern": "^[-\\w\\._,\\(\\)]+$"
+        },
+        "etag": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The etag field is *not* required. If it is provided in the response body, it must also be provided as a header per the normal etag convention.  Entity tags are used for comparing two or more entities from the same requested resource. HTTP/1.1 uses entity tags in the etag (section 14.19), If-Match (section 14.24), If-None-Match (section 14.26), and If-Range (section 14.27) header fields. "
+        },
+        "tags": {
+          "type": "object",
+          "additionalProperties": {
+            "type": "string"
+          },
+          "x-ms-mutability": [
+            "read",
+            "create",
+            "update"
+          ],
+          "description": "Resource tags."
+        },
+        "identity": {
+          "allOf": [
+            {
+              "$ref": "#/definitions/Identity"
+            }
+          ]
+        },
+        "sku": {
+          "allOf": [
+            {
+              "$ref": "#/definitions/Sku"
+            }
+          ]
+        },
+        "plan": {
+          "allOf": [
+            {
+              "$ref": "#/definitions/Plan"
+            }
+          ]
+        }
+      },
+      "x-ms-azure-resource": true
+    },
+    "SkuTier": {
+      "type": "string",
+      "enum": [
+        "Free",
+        "Basic",
+        "Standard",
+        "Premium"
+      ],
+      "x-ms-enum": {
+        "name": "SkuTier",
+        "modelAsString": false
+      },
+      "description": "This field is required to be implemented by the Resource Provider if the service has more than one tier, but is not required on a PUT."
+    },
+    "Sku": {
+      "description": "The resource model definition representing SKU",
+      "type": "object",
+      "properties": {
+        "name": {
+          "type": "string",
+          "description": "The name of the SKU. Ex - P3. It is typically a letter+number code"
+        },
+        "tier": {
+          "$ref": "#/definitions/SkuTier"
+        },
+        "size": {
+          "type": "string",
+          "description": "The SKU size. When the name field is the combination of tier and some other value, this would be the standalone code. "
+        },
+        "family": {
+          "type": "string",
+          "description": "If the service has different generations of hardware, for the same SKU, then that can be captured here."
+        },
+        "capacity": {
+          "type": "integer",
+          "format": "int32",
+          "description": "If the SKU supports scale out/in then the capacity integer should be included. If scale out/in is not possible for the resource this may be omitted."
+        }
+      },
+      "required": [
+        "name"
+      ]
+    },
+    "Identity": {
+      "description": "Identity for the resource.",
+      "type": "object",
+      "properties": {
+        "principalId": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The principal ID of resource identity."
+        },
+        "tenantId": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The tenant ID of resource."
+        },
+        "type": {
+          "type": "string",
+          "description": "The identity type.",
+          "enum": [
+            "SystemAssigned"
+          ],
+          "x-ms-enum": {
+            "name": "ResourceIdentityType",
+            "modelAsString": false
+          }
+        }
+      }
+    },
+    "Plan": {
+      "type": "object",
+      "properties": {
+        "name": {
+          "type": "string",
+          "description": "A user defined name of the 3rd Party Artifact that is being procured."
+        },
+        "publisher": {
+          "type": "string",
+          "description": "The publisher of the 3rd Party Artifact that is being bought. E.g. NewRelic"
+        },
+        "product": {
+          "type": "string",
+          "description": "The 3rd Party artifact that is being procured. E.g. NewRelic. Product maps to the OfferID specified for the artifact at the time of Data Market onboarding. "
+        },
+        "promotionCode": {
+          "type": "string",
+          "description": "A publisher provided promotion code as provisioned in Data Market for the said product/artifact."
+        },
+        "version": {
+          "type": "string",
+          "description": "The version of the desired product/artifact."
+        }
+      },
+      "description": "Plan for the resource.",
+      "required": [
+        "name",
+        "publisher",
+        "product"
+      ]
+    },
+    "ErrorDetail": {
+      "description": "The error detail.",
+      "type": "object",
+      "properties": {
+        "code": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The error code."
+        },
+        "message": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The error message."
+        },
+        "target": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The error target."
+        },
+        "details": {
+          "readOnly": true,
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/ErrorDetail"
+          },
+          "description": "The error details."
+        },
+        "additionalInfo": {
+          "readOnly": true,
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/ErrorAdditionalInfo"
+          },
+          "description": "The error additional info."
+        }
+      }
+    },
+    "ErrorResponse": {
+      "title": "Error response",
+      "description": "Common error response for all Azure Resource Manager APIs to return error details for failed operations. (This also follows the OData error response format.).",
+      "type": "object",
+      "properties": {
+        "error": {
+          "description": "The error object.",
+          "$ref": "#/definitions/ErrorDetail"
+        }
+      }
+    },
+    "ErrorAdditionalInfo": {
+      "type": "object",
+      "properties": {
+        "type": {
+          "readOnly": true,
+          "type": "string",
+          "description": "The additional info type."
+        },
+        "info": {
+          "readOnly": true,
+          "type": "object",
+          "description": "The additional info."
+        }
+      },
+      "description": "The resource management error additional info."
+    },
+    "Operation": {
+      "title": "REST API Operation",
+      "description": "Details of a REST API operation, returned from the Resource Provider Operations API",
+      "type": "object",
+      "properties": {
+        "name": {
+          "description": "The name of the operation, as per Resource-Based Access Control (RBAC). Examples: \"Microsoft.Compute/virtualMachines/write\", \"Microsoft.Compute/virtualMachines/capture/action\"",
+          "type": "string",
+          "readOnly": true
+        },
+        "isDataAction": {
+          "description": "Whether the operation applies to data-plane. This is \"true\" for data-plane operations and \"false\" for ARM/control-plane operations.",
+          "type": "boolean",
+          "readOnly": true
+        },
+        "display": {
+          "description": "Localized display information for this particular operation.",
+          "type": "object",
+          "properties": {
+            "provider": {
+              "description": "The localized friendly form of the resource provider name, e.g. \"Microsoft Monitoring Insights\" or \"Microsoft Compute\".",
+              "type": "string",
+              "readOnly": true
+            },
+            "resource": {
+              "description": "The localized friendly name of the resource type related to this operation. E.g. \"Virtual Machines\" or \"Job Schedule Collections\".",
+              "type": "string",
+              "readOnly": true
+            },
+            "operation": {
+              "description": "The concise, localized friendly name for the operation; suitable for dropdowns. E.g. \"Create or Update Virtual Machine\", \"Restart Virtual Machine\".",
+              "type": "string",
+              "readOnly": true
+            },
+            "description": {
+              "description": "The short, localized friendly description of the operation; suitable for tool tips and detailed views.",
+              "type": "string",
+              "readOnly": true
+            }
+          }
+        },
+        "origin": {
+          "description": "The intended executor of the operation; as in Resource Based Access Control (RBAC) and audit logs UX. Default value is \"user,system\"",
+          "type": "string",
+          "readOnly": true,
+          "enum": [
+            "user",
+            "system",
+            "user,system"
+          ],
+          "x-ms-enum": {
+            "name": "Origin",
+            "modelAsString": true
+          }
+        },
+        "actionType": {
+          "description": "Enum. Indicates the action type. \"Internal\" refers to actions that are for internal only APIs.",
+          "type": "string",
+          "readOnly": true,
+          "enum": [
+            "Internal"
+          ],
+          "x-ms-enum": {
+            "name": "ActionType",
+            "modelAsString": true
+          }
+        }
+      }
+    },
+    "OperationListResult": {
+      "description": "A list of REST API operations supported by an Azure Resource Provider. It contains an URL link to get the next set of results.",
+      "type": "object",
+      "properties": {
+        "value": {
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/Operation"
+          },
+          "description": "List of operations supported by the resource provider",
+          "readOnly": true
+        },
+        "nextLink": {
+          "type": "string",
+          "description": "URL to get the next set of operation list results (if there are any).",
+          "readOnly": true
+        }
+      }
+    },
+    "OperationStatusResult": {
+      "description": "The current status of an async operation.",
+      "type": "object",
+      "required": [
+        "status"
+      ],
+      "properties": {
+        "id": {
+          "description": "Fully qualified ID for the async operation.",
+          "type": "string"
+        },
+        "name": {
+          "description": "Name of the async operation.",
+          "type": "string"
+        },
+        "status": {
+          "description": "Operation status.",
+          "type": "string"
+        },
+        "percentComplete": {
+          "description": "Percent of the operation that is complete.",
+          "type": "number",
+          "minimum": 0,
+          "maximum": 100
+        },
+        "startTime": {
+          "description": "The start time of the operation.",
+          "type": "string",
+          "format": "date-time"
+        },
+        "endTime": {
+          "description": "The end time of the operation.",
+          "type": "string",
+          "format": "date-time"
+        },
+        "operations": {
+          "description": "The operations list.",
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/OperationStatusResult"
+          }
+        },
+        "error": {
+          "description": "If present, details of the operation error.",
+          "$ref": "#/definitions/ErrorDetail"
+        }
+      }
+    },
+    "locationData": {
+      "description": "Metadata pertaining to the geographic location of the resource.",
+      "type": "object",
+      "properties": {
+        "name": {
+          "type": "string",
+          "maxLength": 256,
+          "description": "A canonical name for the geographic or physical location."
+        },
+        "city": {
+          "type": "string",
+          "description": "The city or locality where the resource is located."
+        },
+        "district": {
+          "type": "string",
+          "description": "The district, state, or province where the resource is located."
+        },
+        "countryOrRegion": {
+          "type": "string",
+          "description": "The country or region where the resource is located"
+        }
+      },
+      "required": [
+        "name"
+      ]
+    },
+    "systemData": {
+      "description": "Metadata pertaining to creation and last modification of the resource.",
+      "type": "object",
+      "readOnly": true,
+      "properties": {
+        "createdBy": {
+          "type": "string",
+          "description": "The identity that created the resource."
+        },
+        "createdByType": {
+          "type": "string",
+          "description": "The type of identity that created the resource.",
+          "enum": [
+            "User",
+            "Application",
+            "ManagedIdentity",
+            "Key"
+          ],
+          "x-ms-enum": {
+            "name": "createdByType",
+            "modelAsString": true
+          }
+        },
+        "createdAt": {
+          "type": "string",
+          "format": "date-time",
+          "description": "The timestamp of resource creation (UTC)."
+        },
+        "lastModifiedBy": {
+          "type": "string",
+          "description": "The identity that last modified the resource."
+        },
+        "lastModifiedByType": {
+          "type": "string",
+          "description": "The type of identity that last modified the resource.",
+          "enum": [
+            "User",
+            "Application",
+            "ManagedIdentity",
+            "Key"
+          ],
+          "x-ms-enum": {
+            "name": "createdByType",
+            "modelAsString": true
+          }
+        },
+        "lastModifiedAt": {
+          "type": "string",
+          "format": "date-time",
+          "description": "The timestamp of resource last modification (UTC)"
+        }
+      }
+    },
+    "encryptionProperties": {
+      "description": "Configuration of key for data encryption",
+      "type": "object",
+      "properties": {
+        "status": {
+          "description": "Indicates whether or not the encryption is enabled for container registry.",
+          "enum": [
+            "enabled",
+            "disabled"
+          ],
+          "type": "string",
+          "x-ms-enum": {
+            "name": "EncryptionStatus",
+            "modelAsString": true
+          }
+        },
+        "keyVaultProperties": {
+          "$ref": "#/definitions/KeyVaultProperties",
+          "description": "Key vault properties."
+        }
+      }
+    },
+    "KeyVaultProperties": {
+      "type": "object",
+      "properties": {
+        "keyIdentifier": {
+          "description": "Key vault uri to access the encryption key.",
+          "type": "string"
+        },
+        "identity": {
+          "description": "The client ID of the identity which will be used to access key vault.",
+          "type": "string"
+        }
+      }
+    },
+    "CheckNameAvailabilityRequest": {
+      "description": "The check availability request body.",
+      "type": "object",
+      "properties": {
+        "name": {
+          "description": "The name of the resource for which availability needs to be checked.",
+          "type": "string"
+        },
+        "type": {
+          "description": "The resource type.",
+          "type": "string"
+        }
+      }
+    },
+    "CheckNameAvailabilityResponse": {
+      "description": "The check availability result.",
+      "type": "object",
+      "properties": {
+        "nameAvailable": {
+          "description": "Indicates if the resource name is available.",
+          "type": "boolean"
+        },
+        "reason": {
+          "description": "The reason why the given name is not available.",
+          "type": "string",
+          "enum": [
+            "Invalid",
+            "AlreadyExists"
+          ],
+          "x-ms-enum": {
+            "name": "CheckNameAvailabilityReason",
+            "modelAsString": true
+          }
+        },
+        "message": {
+          "description": "Detailed reason why the given name is available.",
+          "type": "string"
+        }
+      }
+    }
+  },
+  "parameters": {
+    "SubscriptionIdParameter": {
+      "name": "subscriptionId",
+      "in": "path",
+      "required": true,
+      "type": "string",
+      "description": "The ID of the target subscription.",
+      "minLength": 1
+    },
+    "ApiVersionParameter": {
+      "name": "api-version",
+      "in": "query",
+      "required": true,
+      "type": "string",
+      "description": "The API version to use for this operation.",
+      "minLength": 1
+    },
+    "ResourceGroupNameParameter": {
+      "name": "resourceGroupName",
+      "in": "path",
+      "required": true,
+      "type": "string",
+      "description": "The name of the resource group. The name is case insensitive.",
+      "minLength": 1,
+      "maxLength": 90,
+      "x-ms-parameter-location": "method"
+    },
+    "OperationIdParameter": {
+      "name": "operationId",
+      "in": "path",
+      "required": true,
+      "type": "string",
+      "description": "The ID of an ongoing async operation.",
+      "minLength": 1,
+      "x-ms-parameter-location": "method"
+    },
+    "LocationParameter": {
+      "name": "location",
+      "in": "path",
+      "required": true,
+      "type": "string",
+      "description": "The name of Azure region.",
+      "minLength": 1,
+      "x-ms-parameter-location": "method"
+    }
+  }
+}
diff --git a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/examples/List_Install_Versions.json b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/examples/List_Install_Versions.json
index ff0f604e0..5d3b857bb 100644
--- a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/examples/List_Install_Versions.json
+++ b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/examples/List_Install_Versions.json
@@ -1,6 +1,7 @@
 {
   "parameters": {
-    "api-version": "2022-09-04"
+    "api-version": "2022-09-04",
+    "subscriptionId": "subscriptionId"
   },
   "responses": {
     "200": {}
diff --git a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/redhatopenshift.json b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/redhatopenshift.json
index 7246be774..9529e31f1 100644
--- a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/redhatopenshift.json
+++ b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2022-09-04/redhatopenshift.json
@@ -16,24 +16,24 @@
     "application/json"
   ],
   "paths": {
-    "/providers/Microsoft.RedHatOpenShift/listinstallversions": {
+    "/providers/Microsoft.RedHatOpenShift/operations": {
       "get": {
         "tags": [
-          "InstallVersions"
+          "Operations"
         ],
-        "summary": "Lists all OpenShift versions available to install.",
-        "description": "The operation returns the installable OpenShift versions as strings.",
-        "operationId": "List_Install_Versions",
+        "summary": "Lists all of the available RP operations.",
+        "description": "The operation returns the RP operations.",
+        "operationId": "Operations_List",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           }
         ],
         "responses": {
           "200": {
             "description": "OK",
             "schema": {
-              "$ref": "#/definitions/InstallVersions"
+              "$ref": "#/definitions/OperationList"
             }
           },
           "default": {
@@ -44,30 +44,39 @@
           }
         },
         "x-ms-examples": {
-          "Lists all OpenShift versions available to install.": {
-            "$ref": "./examples/List_Install_Versions.json"
+          "Lists all of the available RP operations.": {
+            "$ref": "./examples/Operations_List.json"
           }
+        },
+        "x-ms-pageable": {
+          "nextLinkName": "nextLink"
         }
       }
     },
-    "/providers/Microsoft.RedHatOpenShift/operations": {
+    "/subscriptions/{subscriptionId}/providers/Microsoft.RedHatOpenShift/locations/{location}/listinstallversions": {
       "get": {
         "tags": [
-          "Operations"
+          "InstallVersions"
         ],
-        "summary": "Lists all of the available RP operations.",
-        "description": "The operation returns the RP operations.",
-        "operationId": "Operations_List",
+        "summary": "Lists all OpenShift versions available to install in the specified location.",
+        "description": "The operation returns the installable OpenShift versions as strings.",
+        "operationId": "List_Install_Versions",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
+          },
+          {
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
+          },
+          {
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/LocationParameter"
           }
         ],
         "responses": {
           "200": {
             "description": "OK",
             "schema": {
-              "$ref": "#/definitions/OperationList"
+              "$ref": "#/definitions/InstallVersions"
             }
           },
           "default": {
@@ -78,12 +87,9 @@
           }
         },
         "x-ms-examples": {
-          "Lists all of the available RP operations.": {
-            "$ref": "./examples/Operations_List.json"
+          "Lists all OpenShift versions available to install in the specified location.": {
+            "$ref": "./examples/List_Install_Versions.json"
           }
-        },
-        "x-ms-pageable": {
-          "nextLinkName": "nextLink"
         }
       }
     },
@@ -97,10 +103,10 @@
         "operationId": "OpenShiftClusters_List",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           }
         ],
         "responses": {
@@ -137,13 +143,13 @@
         "operationId": "OpenShiftClusters_ListByResourceGroup",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ResourceGroupNameParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
           }
         ],
         "responses": {
@@ -180,13 +186,13 @@
         "operationId": "OpenShiftClusters_Get",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ResourceGroupNameParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
           },
           {
             "name": "resourceName",
@@ -225,13 +231,13 @@
         "operationId": "OpenShiftClusters_CreateOrUpdate",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ResourceGroupNameParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
           },
           {
             "name": "resourceName",
@@ -286,13 +292,13 @@
         "operationId": "OpenShiftClusters_Delete",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ResourceGroupNameParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
           },
           {
             "name": "resourceName",
@@ -332,13 +338,13 @@
         "operationId": "OpenShiftClusters_Update",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ResourceGroupNameParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
           },
           {
             "name": "resourceName",
@@ -395,13 +401,13 @@
         "operationId": "OpenShiftClusters_ListAdminCredentials",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ResourceGroupNameParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
           },
           {
             "name": "resourceName",
@@ -442,13 +448,13 @@
         "operationId": "OpenShiftClusters_ListCredentials",
         "parameters": [
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ApiVersionParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/SubscriptionIdParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
           },
           {
-            "$ref": "../../../../../common-types/resource-management/v2/types.json#/parameters/ResourceGroupNameParameter"
+            "$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
           },
           {
             "name": "resourceName",
@@ -683,7 +689,7 @@
       "type": "object",
       "allOf": [
         {
-          "$ref": "../../../../../common-types/resource-management/v2/types.json#/definitions/TrackedResource"
+          "$ref": "../../../../../common-types/resource-management/v3/types.json#/definitions/TrackedResource"
         }
       ],
       "properties": {
@@ -693,7 +699,7 @@
           "x-ms-client-flatten": true
         },
         "systemData": {
-          "$ref": "../../../../../common-types/resource-management/v2/types.json#/definitions/systemData",
+          "$ref": "../../../../../common-types/resource-management/v3/types.json#/definitions/systemData",
           "description": "The system meta data relating to this resource.",
           "readOnly": true
         }
@@ -811,7 +817,7 @@
           "type": "string"
         },
         "systemData": {
-          "$ref": "../../../../../common-types/resource-management/v2/types.json#/definitions/systemData",
+          "$ref": "../../../../../common-types/resource-management/v3/types.json#/definitions/systemData",
           "description": "The system meta data relating to this resource.",
           "readOnly": true
         }


Test patch:
diff --git a/pkg/frontend/admin_openshiftcluster_kubernetesobjects_test.go b/pkg/frontend/admin_openshiftcluster_kubernetesobjects_test.go
index bae3bbd56..056e630b7 100644
--- a/pkg/frontend/admin_openshiftcluster_kubernetesobjects_test.go
+++ b/pkg/frontend/admin_openshiftcluster_kubernetesobjects_test.go
@@ -32,6 +32,7 @@ func TestAdminKubernetesObjectsGetAndDelete(t *testing.T) {
 		objKind        string
 		objNamespace   string
 		objName        string
+		force          string
 		mocks          func(*test, *mock_adminactions.MockKubeActions)
 		method         string
 		wantStatusCode int
@@ -101,11 +102,39 @@ func TestAdminKubernetesObjectsGetAndDelete(t *testing.T) {
 			objName:      "config",
 			mocks: func(tt *test, k *mock_adminactions.MockKubeActions) {
 				k.EXPECT().
-					KubeDelete(gomock.Any(), tt.objKind, tt.objNamespace, tt.objName).
+					KubeDelete(gomock.Any(), tt.objKind, tt.objNamespace, tt.objName, false).
 					Return(nil)
 			},
 			wantStatusCode: http.StatusOK,
 		},
+		{
+			method:       http.MethodDelete,
+			name:         "force delete pod",
+			resourceID:   fmt.Sprintf("/subscriptions/%s/resourcegroups/resourceGroup/providers/Microsoft.RedHatOpenShift/openShiftClusters/resourceName", mockSubID),
+			objKind:      "Pod",
+			objNamespace: "openshift",
+			objName:      "aro-pod",
+			force:        "true",
+			mocks: func(tt *test, k *mock_adminactions.MockKubeActions) {
+				k.EXPECT().
+					KubeDelete(gomock.Any(), tt.objKind, tt.objNamespace, tt.objName, true).
+					Return(nil)
+			},
+			wantStatusCode: http.StatusOK,
+		},
+		{
+			method:       http.MethodDelete,
+			name:         "force delete not allowed",
+			resourceID:   fmt.Sprintf("/subscriptions/%s/resourcegroups/resourceGroup/providers/Microsoft.RedHatOpenShift/openShiftClusters/resourceName", mockSubID),
+			objKind:      "ConfigMap",
+			objNamespace: "openshift",
+			objName:      "config",
+			force:        "true",
+			mocks: func(tt *test, k *mock_adminactions.MockKubeActions) {
+			},
+			wantStatusCode: http.StatusForbidden,
+			wantError:      "403: Forbidden: : Force deleting groupKind 'ConfigMap' is forbidden.",
+		},
 		{
 			method:       http.MethodDelete,
 			name:         "no groupKind provided",
@@ -180,8 +209,13 @@ func TestAdminKubernetesObjectsGetAndDelete(t *testing.T) {
 
 			go f.Run(ctx, nil, nil)
 
+			requestStr := fmt.Sprintf("https://server/admin%s/kubernetesObjects?kind=%s&namespace=%s&name=%s", tt.resourceID, tt.objKind, tt.objNamespace, tt.objName)
+			if tt.method == http.MethodDelete && tt.force != "" {
+				requestStr = fmt.Sprintf("%s&force=%s", requestStr, tt.force)
+			}
+
 			resp, b, err := ti.request(tt.method,
-				fmt.Sprintf("https://server/admin%s/kubernetesObjects?kind=%s&namespace=%s&name=%s", tt.resourceID, tt.objKind, tt.objNamespace, tt.objName),
+				requestStr,
 				nil, nil)
 			if err != nil {
 				t.Fatal(err)
diff --git a/pkg/frontend/installversions_list_test.go b/pkg/frontend/installversions_list_test.go
index 1014982e2..8a5ebc107 100644
--- a/pkg/frontend/installversions_list_test.go
+++ b/pkg/frontend/installversions_list_test.go
@@ -46,7 +46,6 @@ func TestListInstallVersions(t *testing.T) {
 		},
 	} {
 		t.Run(fmt.Sprintf("%s: %s", method, tt.name), func(t *testing.T) {
-			resourceProviderNamespace := "Microsoft.RedHatOpenShift"
 			ti := newTestInfra(t).WithSubscriptions()
 			defer ti.done()
 			ti.fixture.AddSubscriptionDocuments(&api.SubscriptionDocument{
@@ -74,7 +73,7 @@ func TestListInstallVersions(t *testing.T) {
 			go f.Run(ctx, nil, nil)
 
 			resp, b, err := ti.request(method,
-				fmt.Sprintf("https://server//providers/%s/listinstallversions?api-version=2022-09-04", resourceProviderNamespace),
+				fmt.Sprintf("https://server/subscriptions/%s/providers/Microsoft.RedHatOpenShift/locations/%s/listinstallversions?api-version=2022-09-04", mockSubID, ti.env.Location()),
 				nil, nil)
 			if err != nil {
 				t.Fatal(err)
diff --git a/test/e2e/adminapi_kubernetesobjects.go b/test/e2e/adminapi_kubernetesobjects.go
index 7f665e69a..26cd829e0 100644
--- a/test/e2e/adminapi_kubernetesobjects.go
+++ b/test/e2e/adminapi_kubernetesobjects.go
@@ -27,8 +27,9 @@ var _ = Describe("[Admin API] Kubernetes objects action", func() {
 
 	When("in a standard openshift namespace", func() {
 		const namespace = "openshift"
+		const containerName = "e2e-test-container-name"
 
-		It("should be able to create, get, list, update and delete objects", func() {
+		It("should be able to create, get, list, update and delete objects, but force delete is only allowed for pods", func() {
 			defer func() {
 				// When ran successfully this test should delete the object,
 				// but we need to remove the object in case of failure
@@ -39,13 +40,22 @@ var _ = Describe("[Admin API] Kubernetes objects action", func() {
 				if !kerrors.IsNotFound(err) {
 					Expect(err).NotTo(HaveOccurred())
 				}
+				By("deleting the pod via Kubernetes API")
+				err = clients.Kubernetes.CoreV1().Pods(namespace).Delete(context.Background(), objName, metav1.DeleteOptions{})
+				// On successfully we expect NotFound error
+				if !kerrors.IsNotFound(err) {
+					Expect(err).NotTo(HaveOccurred())
+				}
 			}()
 
 			testConfigMapCreateOK(objName, namespace)
 			testConfigMapGetOK(objName, namespace)
 			testConfigMapListOK(objName, namespace)
 			testConfigMapUpdateOK(objName, namespace)
+			testConfigMapForceDeleteForbidden(objName, namespace)
 			testConfigMapDeleteOK(objName, namespace)
+			testPodCreateOK(containerName, objName, namespace)
+			testPodForceDeleteOK(objName, namespace)
 		})
 
 		testSecretOperationsForbidden(objName, namespace)
@@ -228,12 +238,28 @@ func testConfigMapUpdateOK(objName, namespace string) {
 	Expect(cm.Data).To(Equal(map[string]string{"key": "new_value"}))
 }
 
+func testConfigMapForceDeleteForbidden(objName, namespace string) {
+	By("force deleting the object via RP admin API")
+	params := url.Values{
+		"kind":      []string{"configmap"},
+		"namespace": []string{namespace},
+		"name":      []string{objName},
+		"force":     []string{"true"},
+	}
+	var cloudErr api.CloudError
+	resp, err := adminRequest(context.Background(), http.MethodDelete, "/admin"+resourceIDFromEnv()+"/kubernetesobjects", params, nil, &cloudErr)
+	Expect(err).NotTo(HaveOccurred())
+	Expect(resp.StatusCode).To(Equal(http.StatusForbidden))
+	Expect(cloudErr.Code).To(Equal(api.CloudErrorCodeForbidden))
+}
+
 func testConfigMapDeleteOK(objName, namespace string) {
 	By("deleting the object via RP admin API")
 	params := url.Values{
 		"kind":      []string{"configmap"},
 		"namespace": []string{namespace},
 		"name":      []string{objName},
+		"force":     []string{"false"},
 	}
 	resp, err := adminRequest(context.Background(), http.MethodDelete, "/admin"+resourceIDFromEnv()+"/kubernetesobjects", params, nil, nil)
 	Expect(err).NotTo(HaveOccurred())
@@ -271,6 +297,7 @@ func testConfigMapDeleteForbidden(objName, namespace string) {
 		"kind":      []string{"configmap"},
 		"namespace": []string{namespace},
 		"name":      []string{objName},
+		"force":     []string{"false"},
 	}
 	var cloudErr api.CloudError
 	resp, err := adminRequest(context.Background(), http.MethodDelete, "/admin"+resourceIDFromEnv()+"/kubernetesobjects", params, nil, &cloudErr)
@@ -279,6 +306,49 @@ func testConfigMapDeleteForbidden(objName, namespace string) {
 	Expect(cloudErr.Code).To(Equal(api.CloudErrorCodeForbidden))
 }
 
+func testPodCreateOK(containerName, objName, namespace string) {
+	By("creating a new pod via RP admin API")
+	obj := mockPod(containerName, objName, namespace)
+	resp, err := adminRequest(context.Background(), http.MethodPost, "/admin"+resourceIDFromEnv()+"/kubernetesobjects", nil, obj, nil)
+	Expect(err).NotTo(HaveOccurred())
+	Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+	By("checking that the pod was created via Kubernetes API")
+	pod, err := clients.Kubernetes.CoreV1().Pods(namespace).Get(context.Background(), objName, metav1.GetOptions{})
+	Expect(err).NotTo(HaveOccurred())
+	Expect(obj.Namespace).To(Equal(pod.Namespace))
+	Expect(obj.Name).To(Equal(pod.Name))
+	Expect(obj.Spec.Containers[0].Name).To(Equal(pod.Spec.Containers[0].Name))
+}
+
+func testPodForceDeleteOK(objName, namespace string) {
+	By("deleting the object via RP admin API")
+	params := url.Values{
+		"kind":      []string{"pod"},
+		"namespace": []string{namespace},
+		"name":      []string{objName},
+		"force":     []string{"true"},
+	}
+	resp, err := adminRequest(context.Background(), http.MethodDelete, "/admin"+resourceIDFromEnv()+"/kubernetesobjects", params, nil, nil)
+	Expect(err).NotTo(HaveOccurred())
+	Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+	// To avoid flakes, we need it to be completely deleted before we can use it again
+	// in a separate run or in a separate It block
+	By("waiting for the pod to be deleted")
+	err = wait.PollImmediate(10*time.Second, time.Minute, func() (bool, error) {
+		_, err = clients.Kubernetes.CoreV1().Pods(namespace).Get(context.Background(), objName, metav1.GetOptions{})
+		if kerrors.IsNotFound(err) {
+			return true, nil
+		}
+		if err != nil {
+			log.Warn(err)
+		}
+		return false, nil // swallow error
+	})
+	Expect(err).NotTo(HaveOccurred())
+}
+
 func mockSecret(name, namespace string) corev1.Secret {
 	return corev1.Secret{
 		TypeMeta: metav1.TypeMeta{
diff --git a/test/e2e/operator.go b/test/e2e/operator.go
index aa56d37f4..bbfa07ec3 100644
--- a/test/e2e/operator.go
+++ b/test/e2e/operator.go
@@ -31,6 +31,7 @@ import (
 
 	arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1"
 	"github.com/Azure/ARO-RP/pkg/operator/controllers/monitoring"
+	"github.com/Azure/ARO-RP/pkg/util/azureclient"
 	"github.com/Azure/ARO-RP/pkg/util/conditions"
 	"github.com/Azure/ARO-RP/pkg/util/ready"
 	"github.com/Azure/ARO-RP/pkg/util/subnet"
@@ -433,10 +434,20 @@ var _ = Describe("ARO Operator - ImageConfig Reconciler", func() {
 	var requiredRegistries []string
 	var imageconfig *configv1.Image
 
-	getLocationRegistries := func(acrDomain, acrDnsSuffix, location string) []string {
-		regionalAcr := fmt.Sprintf("arosvc.%s.data.%s", location, acrDnsSuffix)
-		requiredRegistries := []string{acrDomain, regionalAcr}
-		return requiredRegistries
+	// Reimplementation of function from image config controller
+	getCloudAwareRegistries := func(instance *arov1alpha1.Cluster) ([]string, error) {
+		var requiredRegistries []string
+		switch instance.Spec.AZEnvironment {
+		case azureclient.PublicCloud.Environment.Name:
+			requiredRegistries = []string{instance.Spec.ACRDomain, "arosvc." + instance.Spec.Location + ".data." + azure.PublicCloud.ContainerRegistryDNSSuffix}
+
+		case azureclient.USGovernmentCloud.Environment.Name:
+			requiredRegistries = []string{instance.Spec.ACRDomain, "arosvc." + instance.Spec.Location + ".data." + azure.USGovernmentCloud.ContainerRegistryDNSSuffix}
+
+		default:
+			return nil, fmt.Errorf("cloud environment %s is not supported", instance.Spec.AZEnvironment)
+		}
+		return requiredRegistries, nil
 	}
 
 	sliceEqual := func(a, b []string) bool {
@@ -476,7 +487,9 @@ var _ = Describe("ARO Operator - ImageConfig Reconciler", func() {
 
 		imageconfig, err = clients.ConfigClient.ConfigV1().Images().Get(ctx, "cluster", metav1.GetOptions{})
 		Expect(err).NotTo(HaveOccurred())
-		requiredRegistries = getLocationRegistries(instance.Spec.ACRDomain, "azurecr.io", instance.Spec.Location)
+
+		requiredRegistries, err = getCloudAwareRegistries(instance)
+		Expect(err).NotTo(HaveOccurred())
 	})
 
 	AfterEach(func() {