Repository: FoundationDB/fdb-kubernetes-operator
Pull request #1140 (2022-03-28 09:00:04)

Prepare v1.1.0 release
PR with the changes for the v1.1.0 release.


Patch:
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
index 9dcf72bf..87bb373d 100644
--- a/.github/workflows/pull_request.yml
+++ b/.github/workflows/pull_request.yml
@@ -30,8 +30,7 @@ jobs:
       - name: Install dependencies
         run: sudo dpkg -i fdb.deb
       - name: Run golangci-lint
-        run: |
-          make fmt lint
+        run: make fmt lint
   build:
     name: Build
     runs-on: ubuntu-latest
@@ -49,6 +48,10 @@ jobs:
         go-version: 1.17.6
     - name: Check out code into the Go module directory
       uses: actions/checkout@v2
+      with:
+        fetch-depth: 0
+    - name: Fetch all tags
+      run: git fetch --force --tags
     - uses: actions/cache@v2
       with:
         path: ~/go/pkg/mod
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 880bb9ca..bc256a5c 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -31,63 +31,23 @@ jobs:
           draft: false
           prerelease: false
   release-plugin:
-    runs-on: ${{ matrix.os }}
-    strategy:
-      matrix:
-        os:
-          - ubuntu-latest
-          - macOS-latest
+    runs-on: ubuntu-latest
     needs: create-release
     steps:
-      - uses: actions/checkout@v2
-      - name: Set package name
-        id: set_package_name
-        run: echo ::set-output name=package_name::kubectl-fdb-${{ needs.create-release.outputs.tag }}-$(echo ${RUNNER_OS} | tr [:upper:] [:lower:])
+      - name: Check out code into the Go module directory
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Fetch all tags
+        run: git fetch --force --tags
       - name: Set up Go
         uses: actions/setup-go@v1
         with:
           go-version: 1.17.6
-      - name: Get FDB client
-        if: runner.os != 'Windows'
-        env:
-          FDB_VER: "6.2.29"
-        run: |
-          go get -v -t -d ./...
-          if [[ "${RUNNER_OS}" == "macOS" ]];then
-              curl --fail -L "https://github.com/apple/foundationdb/releases/download/${FDB_VER}/FoundationDB-${FDB_VER}.pkg" -o fdb.pkg
-              sudo installer -allowUntrusted -verbose -pkg ./fdb.pkg -target /
-              # required later for calculating the sha256
-              brew install coreutils
-          else
-              curl --fail -L "https://github.com/apple/foundationdb/releases/download/${FDB_VER}/foundationdb-clients_${FDB_VER}-1_amd64.deb" -o fdb.deb
-              sudo dpkg -i fdb.deb
-          fi
-      - name: Build
-        run: TAG=${{ needs.create-release.outputs.tag }} make plugin package
-      - name: Test binary
-        run: ./bin/kubectl-fdb version --client-only
-      - name: Create sha256 for assert
-        run: |
-          cp ./bin/kubectl-fdb ${{ steps.set_package_name.outputs.package_name }}
-          sha256sum ${{ steps.set_package_name.outputs.package_name }} > ./bin/${{ steps.set_package_name.outputs.package_name }}.sha256
-      - name: Upload Release asset
-        uses: actions/upload-release-asset@v1
+      - name: Release binaries
+        run: make release
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          upload_url: ${{ needs.create-release.outputs.upload_url }}
-          asset_path: ./bin/kubectl-fdb
-          asset_name: ${{ steps.set_package_name.outputs.package_name }}
-          asset_content_type: application/octet-stream
-      - name: Upload sha256 for asset
-        uses: actions/upload-release-asset@v1
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          upload_url: ${{ needs.create-release.outputs.upload_url }}
-          asset_path: ./bin/${{ steps.set_package_name.outputs.package_name }}.sha256
-          asset_name: ${{ steps.set_package_name.outputs.package_name }}.sha256
-          asset_content_type: text/plain
   push_images:
     name: Push Docker images
     needs: create-release
diff --git a/.gitignore b/.gitignore
index 768ca689..7fd15474 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,5 @@ config/default/manager_image_patch.yaml-e
 
 # General temp directory
 tmp/
+
+dist/
diff --git a/.goreleaser.yaml b/.goreleaser.yaml
new file mode 100644
index 00000000..33bb1930
--- /dev/null
+++ b/.goreleaser.yaml
@@ -0,0 +1,36 @@
+before:
+  hooks:
+    - go mod tidy
+builds:
+  - id: kubectl-fdb
+    env:
+      - CGO_ENABLED=0
+    goos:
+      - linux
+      - windows
+      - darwin
+    main: ./kubectl-fdb
+    binary: kubectl-fdb
+    ldflags:
+      - -s -w -X github.com/FoundationDB/fdb-kubernetes-operator/kubectl-fdb/cmd.pluginVersion={{.Version}}
+    goarch:
+      - amd64
+      - arm64
+archives:
+  - id: kubectl-fdb
+    builds:
+    - kubectl-fdb
+    format: binary
+    name_template: "{{ .Binary }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
+    replacements:
+      darwin: Darwin
+      linux: Linux
+      windows: Windows
+      amd64: x86_64
+checksum:
+  name_template: 'checksums.txt'
+snapshot:
+  name_template: "{{ incpatch .Version }}-next"
+# TODO(johscheuer): evaluate if we want to use this feature
+changelog:
+  skip: true
diff --git a/Makefile b/Makefile
index ad96dfde..ac6da2c6 100644
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,8 @@ KUSTOMIZE_PKG?=sigs.k8s.io/kustomize/kustomize/v3@v3.9.4
 KUSTOMIZE=$(GOBIN)/kustomize
 GOLANGCI_LINT_PKG=github.com/golangci/golangci-lint/cmd/golangci-lint@v1.42.1
 GOLANGCI_LINT=$(GOBIN)/golangci-lint
+GORELEASER_PKG=github.com/goreleaser/goreleaser@v1.6.3
+GORELEASER=$(GOBIN)/goreleaser
 BUILD_DEPS?=
 BUILDER?="docker"
 GINKGO_PARALLEL=8
@@ -51,6 +53,7 @@ endef
 $(eval $(call godep,controller-gen,CONTROLLER_GEN))
 $(eval $(call godep,golangci-lint,GOLANGCI_LINT))
 $(eval $(call godep,kustomize,KUSTOMIZE))
+$(eval $(call godep,goreleaser,GORELEASER))
 
 GO_SRC=$(shell find . -name "*.go" -not -name "zz_generated.*.go")
 GENERATED_GO=api/v1beta2/zz_generated.deepcopy.go
@@ -62,7 +65,7 @@ ifeq "$(TEST_RACE_CONDITIONS)" "1"
 	go_test_flags := $(go_test_flags) -race -timeout=30m
 endif
 
-all: deps generate fmt vet manager plugin manifests samples documentation test_if_changed
+all: deps generate fmt vet manager snapshot manifests samples documentation test_if_changed
 
 .PHONY: clean all manager samples documentation run install uninstall deploy manifests fmt vet generate container-build container-push rebuild-operator bounce lint
 
@@ -75,10 +78,11 @@ clean:
 	rm -r bin
 	rm -f $(SAMPLES)
 	rm -f config/rbac/role.yaml
+	rm -rf ./dist/*
 	find . -name "cover.out" -delete
 
 clean-deps:
-	@rm $(CONTROLLER_GEN) $(KUSTOMIZE) $(KUBEBUILDER) $(GOLANGCI_LINT)
+	@rm $(CONTROLLER_GEN) $(KUSTOMIZE) $(GOLANGCI_LINT) $(GORELEASER)
 
 test_if_changed: cover.out
 
@@ -96,18 +100,13 @@ manager: bin/manager
 bin/manager: ${GO_SRC}
 	go build -ldflags="-s -w -X github.com/FoundationDB/fdb-kubernetes-operator/setup.operatorVersion=${TAG}" -o bin/manager main.go
 
-# package the plugin
-package: plugin bin/kubectl-fdb.tar.gz
-
-bin/kubectl-fdb.tar.gz:
-	cp ./kubectl-fdb/Readme.md ./bin
-	(cd ./bin; tar cfvz ./kubectl-fdb.tar.gz ./kubectl-fdb ./Readme.md)
-
 # Build kubectl-fdb binary
 plugin: bin/kubectl-fdb
 
-bin/kubectl-fdb: ${GO_SRC}
-	go build -ldflags="-s -w -X github.com/FoundationDB/fdb-kubernetes-operator/kubectl-fdb/cmd.pluginVersion=${TAG}" -o bin/kubectl-fdb ./kubectl-fdb
+bin/kubectl-fdb: ${GO_SRC} $(GORELEASER)
+	$(GORELEASER) build --single-target --skip-validate --rm-dist
+	@mkdir -p bin
+	@touch $@
 
 # Run against the configured Kubernetes cluster in ~/.kube/config
 run: generate manifests
@@ -140,16 +139,16 @@ fmt: bin/fmt_check
 
 bin/fmt_check: ${GO_ALL}
 	gofmt -w -s .
-	mkdir -p bin
-	@touch bin/fmt_check
+	@mkdir -p bin
+	@touch $@
 
 # Run go vet against code
 vet: bin/vet_check
 
 bin/vet_check: ${GO_ALL}
 	go vet ./...
-	mkdir -p bin
-	@touch bin/vet_check
+	@mkdir -p bin
+	@touch $@
 
 # Generate code
 generate: ${GENERATED_GO}
@@ -191,16 +190,38 @@ config/samples/client.yaml: config/tests/client/*.yaml
 bin/po-docgen: cmd/po-docgen/*.go
 	go build -o bin/po-docgen cmd/po-docgen/main.go  cmd/po-docgen/api.go
 
-docs/cluster_spec.md: bin/po-docgen api/v1beta2/foundationdbcluster_types.go
-	bin/po-docgen api api/v1beta2/foundationdbcluster_types.go > docs/cluster_spec.md
+CLUSTER_DOCS_INPUT=api/v1beta2/foundationdbcluster_types.go api/v1beta2/foundationdb_custom_parameter.go api/v1beta2/foundationdb_database_configuration.go api/v1beta2/foundationdb_process_class.go
+
+docs/cluster_spec.md: bin/po-docgen $(CLUSTER_DOCS_INPUT)
+	bin/po-docgen api $(CLUSTER_DOCS_INPUT) > $@
 
 docs/backup_spec.md: bin/po-docgen api/v1beta2/foundationdbbackup_types.go
-	bin/po-docgen api api/v1beta2/foundationdbbackup_types.go > docs/backup_spec.md
+	bin/po-docgen api api/v1beta2/foundationdbbackup_types.go api/v1beta2/foundationdb_custom_parameter.go > $@
 
 docs/restore_spec.md: bin/po-docgen api/v1beta2/foundationdbrestore_types.go
-	bin/po-docgen api api/v1beta2/foundationdbrestore_types.go > docs/restore_spec.md
+	bin/po-docgen api api/v1beta2/foundationdbrestore_types.go api/v1beta2/foundationdb_custom_parameter.go > $@
 
 documentation: docs/cluster_spec.md docs/backup_spec.md docs/restore_spec.md
 
-lint: golangci-lint
+lint: bin/lint
+
+bin/lint: $(GOLANGCI_LINT) ${GO_SRC}
 	$(GOLANGCI_LINT) run ./...
+	@mkdir -p bin
+	@touch $@
+
+snapshot: bin/snapshot
+
+bin/snapshot: ${GO_SRC} $(GORELEASER)
+	$(GORELEASER) check
+	$(GORELEASER) release --snapshot --rm-dist
+	@mkdir -p bin
+	@touch $@
+
+release: bin/release
+
+bin/release: ${GO_SRC} $(GORELEASER)
+	$(GORELEASER) check
+	$(GORELEASER) release --rm-dist
+	@mkdir -p bin
+	@touch $@
diff --git a/api/v1beta2/foundationdb_database_configuration.go b/api/v1beta2/foundationdb_database_configuration.go
index 47a6bce9..5e168f3f 100644
--- a/api/v1beta2/foundationdb_database_configuration.go
+++ b/api/v1beta2/foundationdb_database_configuration.go
@@ -217,6 +217,62 @@ func (configuration DatabaseConfiguration) getRegion(id string, priority int) Re
 	return matchingRegion
 }
 
+// GetRoleCountsWithDefaults gets the role counts from the cluster spec and
+// fills in default values for any role counts that are 0.
+//
+// The default Storage value will be 2F + 1, where F is the cluster's fault
+// tolerance.
+//
+// The default Logs value will be 3.
+//
+// The default Proxies value will be 3.
+//
+// The default Resolvers value will be 1.
+//
+// The default RemoteLogs value will be equal to the Logs value when the
+// UsableRegions is greater than 1. It will be equal to -1 when the
+// UsableRegions is less than or equal to 1.
+//
+// The default LogRouters value will be equal to 3 times the Logs value when
+// the UsableRegions is greater than 1. It will be equal to -1 when the
+// UsableRegions is less than or equal to 1.
+func (configuration *DatabaseConfiguration) GetRoleCountsWithDefaults(faultTolerance int) RoleCounts {
+	counts := configuration.RoleCounts.DeepCopy()
+	if counts.Storage == 0 {
+		counts.Storage = 2*faultTolerance + 1
+	}
+	if counts.Logs == 0 {
+		counts.Logs = 3
+	}
+	if counts.Proxies == 0 {
+		counts.Proxies = 3
+	}
+	if counts.CommitProxies == 0 {
+		counts.CommitProxies = 2
+	}
+	if counts.GrvProxies == 0 {
+		counts.GrvProxies = 1
+	}
+	if counts.Resolvers == 0 {
+		counts.Resolvers = 1
+	}
+	if counts.RemoteLogs == 0 {
+		if configuration.UsableRegions > 1 {
+			counts.RemoteLogs = counts.Logs
+		} else {
+			counts.RemoteLogs = -1
+		}
+	}
+	if counts.LogRouters == 0 {
+		if configuration.UsableRegions > 1 {
+			counts.LogRouters = counts.Logs
+		} else {
+			counts.LogRouters = -1
+		}
+	}
+	return *counts
+}
+
 // GetNextConfigurationChange produces the next marginal change that should
 // be made to transform this configuration into another configuration.
 //
@@ -454,6 +510,31 @@ func (configuration DatabaseConfiguration) getRegionPriorities() map[string]int
 	return priorities
 }
 
+// AreSeparatedProxiesConfigured returns true if grv_proxies and
+// commit_proxies are greater than 0 (explicitly set) and Proxies is set
+// to 0
+func (configuration DatabaseConfiguration) AreSeparatedProxiesConfigured() bool {
+	counts := configuration.RoleCounts
+	return counts.Proxies == 0 && (counts.GrvProxies > 0 && counts.CommitProxies > 0)
+}
+
+// GetProxiesString returns a string that contains the correct fdbcli
+// commands for use inside the database `configure` command.
+//
+// If the version argument supports the separate grv/commit proxy roles
+// and they have been configured as decided by
+// AreSeparatedProxiesConfigured(), then this function will return the
+// string "commit_proxies=%d grv_proxies=%d", otherwise just
+// "proxies=%d" using the correct counts of the configuration object.
+//
+func (configuration DatabaseConfiguration) GetProxiesString(version Version) string {
+	counts := configuration.GetRoleCountsWithDefaults(DesiredFaultTolerance(configuration.RedundancyMode))
+	if version.HasSeparatedProxies() && configuration.AreSeparatedProxiesConfigured() {
+		return fmt.Sprintf(" commit_proxies=%d grv_proxies=%d", counts.CommitProxies, counts.GrvProxies)
+	}
+	return fmt.Sprintf(" proxies=%d", counts.Proxies)
+}
+
 // FillInDefaultsFromStatus adds in missing fields from the database
 // configuration in the database status to make sure they match the fields that
 // will appear in the cluster spec.
@@ -472,18 +553,29 @@ func (configuration DatabaseConfiguration) FillInDefaultsFromStatus() DatabaseCo
 }
 
 // GetConfigurationString gets the CLI command for configuring a database.
-func (configuration DatabaseConfiguration) GetConfigurationString() (string, error) {
+func (configuration DatabaseConfiguration) GetConfigurationString(version string) (string, error) {
 	configurationString := fmt.Sprintf("%s %s", configuration.RedundancyMode, configuration.StorageEngine)
 
+	fdbVersion, err := ParseFdbVersion(version)
+	if err != nil {
+		return configurationString, err
+	}
+
 	counts := configuration.RoleCounts.Map()
 	configurationString += fmt.Sprintf(" usable_regions=%d", configuration.UsableRegions)
 	// TODO: roleNames !
 	for _, role := range roleNames {
+		if role == "proxies" || role == "commit_proxies" || role == "grv_proxies" {
+			continue
+		}
+
 		if role != ProcessClassStorage {
 			configurationString += fmt.Sprintf(" %s=%d", role, counts[role])
 		}
 	}
 
+	configurationString += configuration.GetProxiesString(fdbVersion)
+
 	flags := configuration.VersionFlags.Map()
 	for flag, value := range flags {
 		if value != 0 {
@@ -588,12 +680,14 @@ const (
 
 // RoleCounts represents the roles whose counts can be customized.
 type RoleCounts struct {
-	Storage    int `json:"storage,omitempty"`
-	Logs       int `json:"logs,omitempty"`
-	Proxies    int `json:"proxies,omitempty"`
-	Resolvers  int `json:"resolvers,omitempty"`
-	LogRouters int `json:"log_routers,omitempty"`
-	RemoteLogs int `json:"remote_logs,omitempty"`
+	Storage       int `json:"storage,omitempty"`
+	Logs          int `json:"logs,omitempty"`
+	Proxies       int `json:"proxies,omitempty"`
+	CommitProxies int `json:"commit_proxies,omitempty"`
+	GrvProxies    int `json:"grv_proxies,omitempty"`
+	Resolvers     int `json:"resolvers,omitempty"`
+	LogRouters    int `json:"log_routers,omitempty"`
+	RemoteLogs    int `json:"remote_logs,omitempty"`
 }
 
 // Map returns a map from process classes to the desired count for that role
@@ -687,6 +781,8 @@ type ProcessCounts struct {
 	Resolution        int `json:"resolution,omitempty"`
 	Tester            int `json:"tester,omitempty"`
 	Proxy             int `json:"proxy,omitempty"`
+	CommitProxy       int `json:"commit_proxy,omitempty"`
+	GrvProxy          int `json:"grv_proxy,omitempty"`
 	Master            int `json:"master,omitempty"`
 	Stateless         int `json:"stateless,omitempty"`
 	Log               int `json:"log,omitempty"`
diff --git a/api/v1beta2/foundationdb_version.go b/api/v1beta2/foundationdb_version.go
index d2c824c6..2eb45052 100644
--- a/api/v1beta2/foundationdb_version.go
+++ b/api/v1beta2/foundationdb_version.go
@@ -140,6 +140,12 @@ func (version Version) HasNonBlockingExcludes(useNonBlockingExcludes bool) bool
 	return version.IsAtLeast(Version{Major: 6, Minor: 3, Patch: 5}) && useNonBlockingExcludes
 }
 
+// HasSeparatedProxies determines if a version has support for separate
+// grv/commit proxies
+func (version Version) HasSeparatedProxies() bool {
+	return version.IsAtLeast(Version{Major: 7, Minor: 0, Patch: 0})
+}
+
 // NextMajorVersion returns the next major version of FoundationDB.
 func (version Version) NextMajorVersion() Version {
 	return Version{Major: version.Major + 1, Minor: 0, Patch: 0}
diff --git a/api/v1beta2/foundationdbcluster_types.go b/api/v1beta2/foundationdbcluster_types.go
index 840d3223..37ba3327 100644
--- a/api/v1beta2/foundationdbcluster_types.go
+++ b/api/v1beta2/foundationdbcluster_types.go
@@ -943,34 +943,7 @@ func (cluster *FoundationDBCluster) GetProcessSettings(processClass ProcessClass
 // the UsableRegions is greater than 1. It will be equal to -1 when the
 // UsableRegions is less than or equal to 1.
 func (cluster *FoundationDBCluster) GetRoleCountsWithDefaults() RoleCounts {
-	counts := cluster.Spec.DatabaseConfiguration.RoleCounts.DeepCopy()
-	if counts.Storage == 0 {
-		counts.Storage = 2*cluster.DesiredFaultTolerance() + 1
-	}
-	if counts.Logs == 0 {
-		counts.Logs = 3
-	}
-	if counts.Proxies == 0 {
-		counts.Proxies = 3
-	}
-	if counts.Resolvers == 0 {
-		counts.Resolvers = 1
-	}
-	if counts.RemoteLogs == 0 {
-		if cluster.Spec.DatabaseConfiguration.UsableRegions > 1 {
-			counts.RemoteLogs = counts.Logs
-		} else {
-			counts.RemoteLogs = -1
-		}
-	}
-	if counts.LogRouters == 0 {
-		if cluster.Spec.DatabaseConfiguration.UsableRegions > 1 {
-			counts.LogRouters = counts.Logs
-		} else {
-			counts.LogRouters = -1
-		}
-	}
-	return *counts
+	return cluster.Spec.DatabaseConfiguration.GetRoleCountsWithDefaults(cluster.DesiredFaultTolerance())
 }
 
 // calculateProcessCount determines the process count from a given role count.
@@ -1076,10 +1049,23 @@ func (cluster *FoundationDBCluster) GetProcessCountsWithDefaults() (ProcessCount
 	if processCounts.Stateless == 0 {
 		primaryStatelessCount := cluster.calculateProcessCountFromRole(1, processCounts.Master) +
 			cluster.calculateProcessCountFromRole(1, processCounts.ClusterController) +
-			cluster.calculateProcessCountFromRole(roleCounts.Proxies, processCounts.Proxy) +
 			cluster.calculateProcessCountFromRole(roleCounts.Resolvers, processCounts.Resolution)
 		primaryStatelessCount += cluster.calculateProcessCountFromRole(1, processCounts.Ratekeeper) +
 			cluster.calculateProcessCountFromRole(1, processCounts.DataDistributor)
+
+		fdbVersion, err := ParseFdbVersion(cluster.Spec.Version)
+		if err != nil {
+			return *processCounts, err
+		}
+
+		if fdbVersion.HasSeparatedProxies() {
+			primaryStatelessCount += cluster.calculateProcessCountFromRole(roleCounts.GrvProxies, processCounts.GrvProxy)
+			primaryStatelessCount += cluster.calculateProcessCountFromRole(roleCounts.CommitProxies, processCounts.CommitProxy)
+		} else {
+			primaryStatelessCount += cluster.calculateProcessCountFromRole(roleCounts.Proxies, processCounts.Proxy)
+
+		}
+
 		processCounts.Stateless = cluster.calculateProcessCount(true,
 			primaryStatelessCount,
 			cluster.calculateProcessCountFromRole(roleCounts.LogRouters),
@@ -1736,8 +1722,10 @@ func (cluster *FoundationDBCluster) GetMaxConcurrentAutomaticReplacements() int
 // CoordinatorSelectionSetting defines the process class and the priority of it.
 // A higher priority means that the process class is preferred over another.
 type CoordinatorSelectionSetting struct {
+	// ProcessClass defines the process class to associate with priority with.
 	ProcessClass ProcessClass `json:"processClass,omitempty"`
-	Priority     int          `json:"priority,omitempty"`
+	// Priority defines the ordering of different process classes.
+	Priority int `json:"priority,omitempty"`
 }
 
 // IsEligibleAsCandidate checks if the given process has the right process class to be considered a valid coordinator.
diff --git a/cmd/po-docgen/api.go b/cmd/po-docgen/api.go
index 736c758f..cf95f2e3 100644
--- a/cmd/po-docgen/api.go
+++ b/cmd/po-docgen/api.go
@@ -26,29 +26,29 @@ import (
 )
 
 const (
-	firstParagraph = `<br>
-# API Docs
+	firstParagraph = `# API Docs
+
 This Document documents the types introduced by the FoundationDB Operator to be consumed by users.
 > Note this document is generated from code comments. When contributing a change to this document please do so by changing the code comments.`
 )
 
 var (
 	links = map[string]string{
-		"metav1.ObjectMeta":            "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta",
-		"metav1.ListMeta":              "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#listmeta-v1-meta",
-		"metav1.LabelSelector":         "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta",
-		"corev1.ResourceRequirements":  "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#resourcerequirements-v1-core",
-		"corev1.LocalObjectReference":  "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#localobjectreference-v1-core",
-		"corev1.SecretKeySelector":     "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core",
-		"corev1.PersistentVolumeClaim": "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#persistentvolumeclaim-v1-core",
-		"corev1.EmptyDirVolumeSource":  "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#emptydirvolumesource-v1-core",
-		"corev1.Container":             "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#container-v1-core",
-		"corev1.PodSecurityContext":    "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#podsecuritycontext-v1-core",
-		"corev1.SecurityContext":       "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#securitycontext-v1-core",
-		"corev1.EnvVar":                "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvar-v1-core",
-		"corev1.VolumeMount":           "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#volumemount-v1-core",
-		"corev1.PodTemplateSpec":       "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#podtemplatespec-v1-core",
-		"corev1.ConfigMap":             "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#configmap-v1-core",
+		"metav1.ObjectMeta":            "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta",
+		"metav1.ListMeta":              "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#listmeta-v1-meta",
+		"metav1.LabelSelector":         "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#labelselector-v1-meta",
+		"corev1.ResourceRequirements":  "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core",
+		"corev1.LocalObjectReference":  "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#localobjectreference-v1-core",
+		"corev1.SecretKeySelector":     "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#secretkeyselector-v1-core",
+		"corev1.PersistentVolumeClaim": "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#persistentvolumeclaim-v1-core",
+		"corev1.EmptyDirVolumeSource":  "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#emptydirvolumesource-v1-core",
+		"corev1.Container":             "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#container-v1-core",
+		"corev1.PodSecurityContext":    "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core",
+		"corev1.SecurityContext":       "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core",
+		"corev1.EnvVar":                "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#envvar-v1-core",
+		"corev1.VolumeMount":           "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#volumemount-v1-core",
+		"corev1.PodTemplateSpec":       "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podtemplatespec-v1-core",
+		"corev1.ConfigMap":             "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#configmap-v1-core",
 	}
 
 	selfLinks = map[string]string{}
@@ -61,7 +61,7 @@ func toSectionLink(name string) string {
 }
 
 func printTOC(types []KubeTypes) {
-	fmt.Printf("\n## Table of Contents\n")
+	fmt.Printf("\n## Table of Contents\n\n")
 	for _, t := range types {
 		strukt := t[0]
 		if len(t) > 1 {
@@ -97,11 +97,14 @@ func printAPIDocs(paths []string) {
 			}
 			fmt.Println("")
 			fmt.Println("[Back to TOC](#table-of-contents)")
+		} else {
+			fmt.Printf("\n## %s\n\n%s\n\n", strukt.Name, strukt.Doc)
+			fmt.Println("[Back to TOC](#table-of-contents)")
 		}
 	}
 }
 
-// Pair of strings. We keed the name of fields and the doc
+// Pair of strings. We keep the name of fields and the doc
 type Pair struct {
 	Name, Doc, Type string
 	Mandatory       bool
@@ -121,12 +124,14 @@ func ParseDocumentationFrom(srcs []string) []KubeTypes {
 		pkg := astFrom(src)
 
 		for _, kubType := range pkg.Types {
+
 			if structType, ok := kubType.Decl.Specs[0].(*ast.TypeSpec).Type.(*ast.StructType); ok {
 				var ks KubeTypes
 				ks = append(ks, Pair{kubType.Name, fmtRawDoc(kubType.Doc), "", false})
 
 				for _, field := range structType.Fields.List {
 					typeString := fieldType(field.Type)
+
 					fieldMandatory := fieldRequired(field)
 					if n := fieldName(field); n != "-" {
 						fieldDoc := fmtRawDoc(field.Doc.Text())
@@ -134,6 +139,9 @@ func ParseDocumentationFrom(srcs []string) []KubeTypes {
 					}
 				}
 				docForTypes = append(docForTypes, ks)
+			} else if i, ok := kubType.Decl.Specs[0].(*ast.TypeSpec).Type.(*ast.Ident); ok {
+				// Add documentation for typed string that are not structs.
+				docForTypes = append(docForTypes, KubeTypes{Pair{kubType.Name, fmtRawDoc(kubType.Doc), i.Name, false}})
 			}
 		}
 	}
diff --git a/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml b/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml
index 18ff978c..6e139e2f 100644
--- a/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml
+++ b/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml
@@ -9423,6 +9423,10 @@ spec:
                 type: string
               databaseConfiguration:
                 properties:
+                  commit_proxies:
+                    type: integer
+                  grv_proxies:
+                    type: integer
                   log_routers:
                     type: integer
                   log_spill:
@@ -9589,12 +9593,16 @@ spec:
                     type: integer
                   cluster_controller:
                     type: integer
+                  commit_proxy:
+                    type: integer
                   coordinator:
                     type: integer
                   data_distributor:
                     type: integer
                   fast_restore:
                     type: integer
+                  grv_proxy:
+                    type: integer
                   log:
                     type: integer
                   master:
@@ -12807,6 +12815,10 @@ spec:
                 type: string
               databaseConfiguration:
                 properties:
+                  commit_proxies:
+                    type: integer
+                  grv_proxies:
+                    type: integer
                   log_routers:
                     type: integer
                   log_spill:
diff --git a/config/deployment/manager.yaml b/config/deployment/manager.yaml
index 6f6d1dd1..4c7692a1 100644
--- a/config/deployment/manager.yaml
+++ b/config/deployment/manager.yaml
@@ -66,7 +66,7 @@ spec:
       containers:
       - command:
         - /manager
-        image: foundationdb/fdb-kubernetes-operator:v1.0.0
+        image: foundationdb/fdb-kubernetes-operator:v1.1.0
         name: manager
         env:
           - name: WATCH_NAMESPACE
diff --git a/config/samples/deployment.yaml b/config/samples/deployment.yaml
index 8daacbcd..29d666ba 100644
--- a/config/samples/deployment.yaml
+++ b/config/samples/deployment.yaml
@@ -150,7 +150,7 @@ spec:
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
-        image: foundationdb/fdb-kubernetes-operator:v1.0.0
+        image: foundationdb/fdb-kubernetes-operator:v1.1.0
         name: manager
         ports:
         - containerPort: 8080
diff --git a/controllers/admin_client_mock.go b/controllers/admin_client_mock.go
index 49fd1a5f..32801d54 100644
--- a/controllers/admin_client_mock.go
+++ b/controllers/admin_client_mock.go
@@ -315,7 +315,7 @@ func (client *mockAdminClient) GetStatus() (*fdbv1beta2.FoundationDBStatus, erro
 }
 
 // ConfigureDatabase changes the database configuration
-func (client *mockAdminClient) ConfigureDatabase(configuration fdbv1beta2.DatabaseConfiguration, _ bool) error {
+func (client *mockAdminClient) ConfigureDatabase(configuration fdbv1beta2.DatabaseConfiguration, _ bool, _ string) error {
 	adminClientMutex.Lock()
 	defer adminClientMutex.Unlock()
 
diff --git a/controllers/update_database_configuration.go b/controllers/update_database_configuration.go
index 97cffb0e..35896ab4 100644
--- a/controllers/update_database_configuration.go
+++ b/controllers/update_database_configuration.go
@@ -76,7 +76,7 @@ func (u updateDatabaseConfiguration) reconcile(ctx context.Context, r *Foundatio
 		} else {
 			nextConfiguration = currentConfiguration.GetNextConfigurationChange(desiredConfiguration)
 		}
-		configurationString, _ := nextConfiguration.GetConfigurationString()
+		configurationString, _ := nextConfiguration.GetConfigurationString(cluster.Spec.Version)
 		var enabled = cluster.Spec.AutomationOptions.ConfigureDatabase
 
 		if !dataHealthy {
@@ -109,7 +109,7 @@ func (u updateDatabaseConfiguration) reconcile(ctx context.Context, r *Foundatio
 		r.Recorder.Event(cluster, corev1.EventTypeNormal, "ConfiguringDatabase",
 			fmt.Sprintf("Setting database configuration to `%s`", configurationString),
 		)
-		err = adminClient.ConfigureDatabase(nextConfiguration, initialConfig)
+		err = adminClient.ConfigureDatabase(nextConfiguration, initialConfig, cluster.Spec.Version)
 		if err != nil {
 			return &requeue{curError: err}
 		}
diff --git a/docs/backup_spec.md b/docs/backup_spec.md
index 4a214700..4a1b6ce2 100644
--- a/docs/backup_spec.md
+++ b/docs/backup_spec.md
@@ -1,9 +1,10 @@
-<br>
 # API Docs
+
 This Document documents the types introduced by the FoundationDB Operator to be consumed by users.
 > Note this document is generated from code comments. When contributing a change to this document please do so by changing the code comments.
 
 ## Table of Contents
+
 * [BackupGenerationStatus](#backupgenerationstatus)
 * [BlobStoreConfiguration](#blobstoreconfiguration)
 * [FoundationDBBackup](#foundationdbbackup)
@@ -29,6 +30,12 @@ BackupGenerationStatus stores information on which generations have reached diff
 
 [Back to TOC](#table-of-contents)
 
+## BackupState
+
+BackupState defines the desired state of a backup
+
+[Back to TOC](#table-of-contents)
+
 ## BlobStoreConfiguration
 
 BlobStoreConfiguration describes the blob store configuration.
@@ -38,7 +45,7 @@ BlobStoreConfiguration describes the blob store configuration.
 | backupName | The name for the backup. If empty defaults to .metadata.name. | string | false |
 | accountName | The account name to use with the backup destination. | string | true |
 | bucket | The backup bucket to write to. The default is \"fdb-backups\". | string | false |
-| urlParameters | Additional URL parameters passed to the blobstore URL. | []URLParameter | false |
+| urlParameters | Additional URL parameters passed to the blobstore URL. | [][URLParameter](#urlparameter) | false |
 
 [Back to TOC](#table-of-contents)
 
@@ -48,7 +55,7 @@ FoundationDBBackup is the Schema for the foundationdbbackups API
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| metadata |  | [metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta) | false |
+| metadata |  | [metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta) | false |
 | spec |  | [FoundationDBBackupSpec](#foundationdbbackupspec) | false |
 | status |  | [FoundationDBBackupStatus](#foundationdbbackupstatus) | false |
 
@@ -60,7 +67,7 @@ FoundationDBBackupList contains a list of FoundationDBBackup objects
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| metadata |  | [metav1.ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#listmeta-v1-meta) | false |
+| metadata |  | [metav1.ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#listmeta-v1-meta) | false |
 | items |  | [][FoundationDBBackup](#foundationdbbackup) | true |
 
 [Back to TOC](#table-of-contents)
@@ -73,11 +80,11 @@ FoundationDBBackupSpec describes the desired state of the backup for a cluster.
 | ----- | ----------- | ------ | -------- |
 | version | The version of FoundationDB that the backup agents should run. | string | true |
 | clusterName | The cluster this backup is for. | string | true |
-| backupState | The desired state of the backup. The default is Running. | BackupState | false |
+| backupState | The desired state of the backup. The default is Running. | [BackupState](#backupstate) | false |
 | agentCount | AgentCount defines the number of backup agents to run. The default is run 2 agents. | *int | false |
 | snapshotPeriodSeconds | The time window between new snapshots. This is measured in seconds. The default is 864,000, or 10 days. | *int | false |
-| backupDeploymentMetadata | BackupDeploymentMetadata allows customizing labels and annotations on the deployment for the backup agents. | *[metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta) | false |
-| podTemplateSpec | PodTemplateSpec allows customizing the pod template for the backup agents. | *[corev1.PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#podtemplatespec-v1-core) | false |
+| backupDeploymentMetadata | BackupDeploymentMetadata allows customizing labels and annotations on the deployment for the backup agents. | *[metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta) | false |
+| podTemplateSpec | PodTemplateSpec allows customizing the pod template for the backup agents. | *[corev1.PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podtemplatespec-v1-core) | false |
 | customParameters | CustomParameters defines additional parameters to pass to the backup agents. | FoundationDBCustomParameters | false |
 | allowTagOverride | This setting defines if a user provided image can have it's own tag rather than getting the provided version appended. You have to ensure that the specified version in the Spec is compatible with the given version in your custom image. | *bool | false |
 | blobStoreConfiguration | This is the configuration of the target blobstore for this backup. | *[BlobStoreConfiguration](#blobstoreconfiguration) | false |
@@ -132,3 +139,15 @@ FoundationDBLiveBackupStatusState provides the state of a backup in the backup s
 | Running | Running determines whether the backup is currently running. | bool | false |
 
 [Back to TOC](#table-of-contents)
+
+## URLParameter
+
+URLParameter defines a single URL parameter to pass to the blobstore.
+
+[Back to TOC](#table-of-contents)
+
+## FoundationDBCustomParameter
+
+FoundationDBCustomParameter defines a single custom knob
+
+[Back to TOC](#table-of-contents)
diff --git a/docs/changelog/v1.1.0.md b/docs/changelog/v1.1.0.md
new file mode 100644
index 00000000..2b60c9bb
--- /dev/null
+++ b/docs/changelog/v1.1.0.md
@@ -0,0 +1,16 @@
+# v1.1.0
+
+## Changes
+
+* Unify kustomize setup and reduce duplication [#1084](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1084).
+* Pass configured logger into fdbclient [#1111](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1111).
+* Add an image pull policy in the development operator config [#1115](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1115).
+* Changes to support coordinator changes when using DNS names [#1122](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1122).
+* Remove the usage of go get and unused dep [#1124](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1124).
+* Fix flaky unit test and bug in process group removal [#1129](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1129).
+* Add authentication support for OpenStack, Azure and GCP [#1130](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1130).
+* Run specs in parallel [#1125](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1125).
+* Remove unused deps and use make to install required versions [#1127](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1127).
+* Correct the generation of our spec documentation to include structs from different files [#1137](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1137).
+* Make use of [goreleaser](https://goreleaser.com) for our plugin [#1139](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1139).
+* Add support for grv and commit proxies for FDB 7.0+ [#1114](https://github.com/FoundationDB/fdb-kubernetes-operator/pull/1114).
diff --git a/docs/cluster_spec.md b/docs/cluster_spec.md
index 0d9bb195..08bae706 100644
--- a/docs/cluster_spec.md
+++ b/docs/cluster_spec.md
@@ -1,9 +1,10 @@
-<br>
 # API Docs
+
 This Document documents the types introduced by the FoundationDB Operator to be consumed by users.
 > Note this document is generated from code comments. When contributing a change to this document please do so by changing the code comments.
 
 ## Table of Contents
+
 * [AutomaticReplacementOptions](#automaticreplacementoptions)
 * [BuggifyConfig](#buggifyconfig)
 * [ClusterGenerationStatus](#clustergenerationstatus)
@@ -27,6 +28,12 @@ This Document documents the types introduced by the FoundationDB Operator to be
 * [ProcessSettings](#processsettings)
 * [RequiredAddressSet](#requiredaddressset)
 * [RoutingConfig](#routingconfig)
+* [DataCenter](#datacenter)
+* [DatabaseConfiguration](#databaseconfiguration)
+* [ProcessCounts](#processcounts)
+* [Region](#region)
+* [RoleCounts](#rolecounts)
+* [VersionFlags](#versionflags)
 
 ## AutomaticReplacementOptions
 
@@ -120,8 +127,8 @@ CoordinatorSelectionSetting defines the process class and the priority of it. A
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| processClass |  | ProcessClass | false |
-| priority |  | int | false |
+| processClass | ProcessClass defines the process class to associate with priority with. | [ProcessClass](#processclass) | false |
+| priority | Priority defines the ordering of different process classes. | int | false |
 
 [Back to TOC](#table-of-contents)
 
@@ -131,7 +138,7 @@ FoundationDBCluster is the Schema for the foundationdbclusters API
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| metadata |  | [metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta) | false |
+| metadata |  | [metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta) | false |
 | spec |  | [FoundationDBClusterSpec](#foundationdbclusterspec) | false |
 | status |  | [FoundationDBClusterStatus](#foundationdbclusterstatus) | false |
 
@@ -150,10 +157,10 @@ FoundationDBClusterAutomationOptions provides flags for enabling or disabling op
 | useNonBlockingExcludes | UseNonBlockingExcludes defines whether the operator is allowed to use non blocking exclude commands. The default is false. | *bool | false |
 | ignoreTerminatingPodsSeconds | IgnoreTerminatingPodsSeconds defines how long a Pod has to be in the Terminating Phase before we ignore it during reconciliation. This prevents Pod that are stuck in Terminating to block further reconciliation. | *int | false |
 | maxConcurrentReplacements | MaxConcurrentReplacements defines how many process groups can be concurrently replaced if they are misconfigured. If the value will be set to 0 this will block replacements and these misconfigured Pods must be replaced manually or by another process. For each reconcile loop the operator calculates the maximum number of possible replacements by taken this value as the upper limit and removes all ongoing replacements that have not finished. Which means if the value is set to 5 and we have 4 ongoing replacements (process groups marked with remove but not excluded) the operator is allowed to replace on further process group. | *int | false |
-| deletionMode | DeletionMode defines the deletion mode for this cluster. This can be PodUpdateModeNone, PodUpdateModeAll, PodUpdateModeZone or PodUpdateModeProcessGroup. The DeletionMode defines how Pods are deleted in order to update them or when they are removed. | PodUpdateMode | false |
-| removalMode | RemovalMode defines the removal mode for this cluster. This can be PodUpdateModeNone, PodUpdateModeAll, PodUpdateModeZone or PodUpdateModeProcessGroup. The RemovalMode defines how process groups are deleted in order when they are marked for removal. | PodUpdateMode | false |
+| deletionMode | DeletionMode defines the deletion mode for this cluster. This can be PodUpdateModeNone, PodUpdateModeAll, PodUpdateModeZone or PodUpdateModeProcessGroup. The DeletionMode defines how Pods are deleted in order to update them or when they are removed. | [PodUpdateMode](#podupdatemode) | false |
+| removalMode | RemovalMode defines the removal mode for this cluster. This can be PodUpdateModeNone, PodUpdateModeAll, PodUpdateModeZone or PodUpdateModeProcessGroup. The RemovalMode defines how process groups are deleted in order when they are marked for removal. | [PodUpdateMode](#podupdatemode) | false |
 | waitBetweenRemovalsSeconds | WaitBetweenRemovalsSeconds defines how long to wait between the last removal and the next removal. This is only an upper limit if the process group and the according resources are deleted faster than the provided duration the operator will move on with the next removal. The idea is to prevent a race condition were the operator deletes a resource but the Kubernetes API is slower to trigger the actual deletion, and we are running into a situation where the fault tolerance check still includes the already deleted processes. Defaults to 60. | *int | false |
-| podUpdateStrategy | PodUpdateStrategy defines how Pod spec changes are rolled out either by replacing Pods or by deleting Pods. The default for this is ReplaceTransactionSystem. | PodUpdateStrategy | false |
+| podUpdateStrategy | PodUpdateStrategy defines how Pod spec changes are rolled out either by replacing Pods or by deleting Pods. The default for this is ReplaceTransactionSystem. | [PodUpdateStrategy](#podupdatestrategy) | false |
 
 [Back to TOC](#table-of-contents)
 
@@ -177,7 +184,7 @@ FoundationDBClusterList contains a list of FoundationDBCluster objects
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| metadata |  | [metav1.ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#listmeta-v1-meta) | false |
+| metadata |  | [metav1.ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#listmeta-v1-meta) | false |
 | items |  | [][FoundationDBCluster](#foundationdbcluster) | true |
 
 [Back to TOC](#table-of-contents)
@@ -189,15 +196,15 @@ FoundationDBClusterSpec defines the desired state of a cluster.
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
 | version | Version defines the version of FoundationDB the cluster should run. | string | true |
-| databaseConfiguration | DatabaseConfiguration defines the database configuration. | DatabaseConfiguration | false |
-| processes | Processes defines process-level settings. | map[ProcessClass][ProcessSettings](#processsettings) | false |
-| processCounts | ProcessCounts defines the number of processes to configure for each process class. You can generally omit this, to allow the operator to infer the process counts based on the database configuration. | ProcessCounts | false |
+| databaseConfiguration | DatabaseConfiguration defines the database configuration. | [DatabaseConfiguration](#databaseconfiguration) | false |
+| processes | Processes defines process-level settings. | map[[ProcessClass](#processclass)][ProcessSettings](#processsettings) | false |
+| processCounts | ProcessCounts defines the number of processes to configure for each process class. You can generally omit this, to allow the operator to infer the process counts based on the database configuration. | [ProcessCounts](#processcounts) | false |
 | seedConnectionString | SeedConnectionString provides a connection string for the initial reconciliation.  After the initial reconciliation, this will not be used. | string | false |
 | partialConnectionString | PartialConnectionString provides a way to specify part of the connection string (e.g. the database name and coordinator generation) without specifying the entire string. This does not allow for setting the coordinator IPs. If `SeedConnectionString` is set, `PartialConnectionString` will have no effect. They cannot be used together. | [ConnectionString](#connectionstring) | false |
 | faultDomain | FaultDomain defines the rules for what fault domain to replicate across. | [FoundationDBClusterFaultDomain](#foundationdbclusterfaultdomain) | false |
 | processGroupsToRemove | ProcessGroupsToRemove defines the process groups that we should remove from the cluster. This list contains the process group IDs. | []string | false |
 | processGroupsToRemoveWithoutExclusion | ProcessGroupsToRemoveWithoutExclusion defines the process groups that we should remove from the cluster without excluding them. This list contains the process group IDs.  This should be used for cases where a pod does not have an IP address and you want to remove it and destroy its volume without confirming the data is fully replicated. | []string | false |
-| configMap | ConfigMap allows customizing the config map the operator creates. | *[corev1.ConfigMap](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#configmap-v1-core) | false |
+| configMap | ConfigMap allows customizing the config map the operator creates. | *[corev1.ConfigMap](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#configmap-v1-core) | false |
 | mainContainer | MainContainer defines customization for the foundationdb container. | [ContainerOverrides](#containeroverrides) | false |
 | sidecarContainer | SidecarContainer defines customization for the foundationdb-kubernetes-sidecar container. | [ContainerOverrides](#containeroverrides) | false |
 | trustedCAs | TrustedCAs defines a list of root CAs the cluster should trust, in PEM format. | []string | false |
@@ -228,7 +235,7 @@ FoundationDBClusterStatus defines the observed state of FoundationDBCluster
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| databaseConfiguration | DatabaseConfiguration provides the running configuration of the database. | DatabaseConfiguration | false |
+| databaseConfiguration | DatabaseConfiguration provides the running configuration of the database. | [DatabaseConfiguration](#databaseconfiguration) | false |
 | generations | Generations provides information about the latest generation to be reconciled, or to reach other stages at which reconciliation can halt. | [ClusterGenerationStatus](#clustergenerationstatus) | false |
 | health | Health provides information about the health of the database. | [ClusterHealth](#clusterhealth) | false |
 | requiredAddresses | RequiredAddresses define that addresses that we need to enable for the processes in the cluster. | [RequiredAddressSet](#requiredaddressset) | false |
@@ -240,7 +247,7 @@ FoundationDBClusterStatus defines the observed state of FoundationDBCluster
 | configured | Configured defines whether we have configured the database yet. | bool | false |
 | hasListenIPsForAllPods | HasListenIPsForAllPods defines whether every pod has an environment variable for its listen address. | bool | false |
 | storageServersPerDisk | StorageServersPerDisk defines the storageServersPerPod observed in the cluster. If there are more than one value in the slice the reconcile phase is not finished. | []int | false |
-| imageTypes | ImageTypes defines the kinds of images that are in use in the cluster. If there is more than one value in the slice the reconcile phase is not finished. | []ImageType | false |
+| imageTypes | ImageTypes defines the kinds of images that are in use in the cluster. If there is more than one value in the slice the reconcile phase is not finished. | [][ImageType](#imagetype) | false |
 | processGroups | ProcessGroups contain information about a process group. This information is used in multiple places to trigger the according action. | []*[ProcessGroupStatus](#processgroupstatus) | false |
 | locks | Locks contains information about the locking system. | [LockSystemStatus](#locksystemstatus) | false |
 
@@ -259,6 +266,12 @@ ImageConfig provides a policy for customizing an image.  When multiple image con
 
 [Back to TOC](#table-of-contents)
 
+## ImageType
+
+ImageType defines a single kind of images used in the cluster.
+
+[Back to TOC](#table-of-contents)
+
 ## LabelConfig
 
 LabelConfig allows customizing labels used by the operator.
@@ -307,17 +320,35 @@ LockSystemStatus provides a summary of the status of the locking system.
 
 [Back to TOC](#table-of-contents)
 
+## PodUpdateMode
+
+PodUpdateMode defines the deletion mode for the cluster
+
+[Back to TOC](#table-of-contents)
+
+## PodUpdateStrategy
+
+PodUpdateStrategy defines how Pod spec changes should be applied.
+
+[Back to TOC](#table-of-contents)
+
 ## ProcessGroupCondition
 
 ProcessGroupCondition represents a degraded condition that a process group is in.
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| type | Name of the condition | ProcessGroupConditionType | false |
+| type | Name of the condition | [ProcessGroupConditionType](#processgroupconditiontype) | false |
 | timestamp | Timestamp when the Condition was observed | int64 | false |
 
 [Back to TOC](#table-of-contents)
 
+## ProcessGroupConditionType
+
+ProcessGroupConditionType represents a concrete ProcessGroupCondition.
+
+[Back to TOC](#table-of-contents)
+
 ## ProcessGroupStatus
 
 ProcessGroupStatus represents the status of a ProcessGroup.
@@ -325,7 +356,7 @@ ProcessGroupStatus represents the status of a ProcessGroup.
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
 | processGroupID | ProcessGroupID represents the ID of the process group | string | false |
-| processClass | ProcessClass represents the class the process group has. | ProcessClass | false |
+| processClass | ProcessClass represents the class the process group has. | [ProcessClass](#processclass) | false |
 | addresses | Addresses represents the list of addresses the process group has been known to have. | []string | false |
 | removalTimestamp | RemoveTimestamp if not empty defines when the process group was marked for removal. | *metav1.Time | false |
 | exclusionTimestamp | ExcludedTimestamp defines when the process group has been fully excluded. This is only used within the reconciliation process, and should not be considered authoritative. | *metav1.Time | false |
@@ -340,12 +371,18 @@ ProcessSettings defines process-level settings.
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| podTemplate | PodTemplate allows customizing the pod. If a container image with a tag is specified the operator will throw an error and stop processing the cluster. | *[corev1.PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#podtemplatespec-v1-core) | false |
-| volumeClaimTemplate | VolumeClaimTemplate allows customizing the persistent volume claim for the pod. | *[corev1.PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#persistentvolumeclaim-v1-core) | false |
+| podTemplate | PodTemplate allows customizing the pod. If a container image with a tag is specified the operator will throw an error and stop processing the cluster. | *[corev1.PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podtemplatespec-v1-core) | false |
+| volumeClaimTemplate | VolumeClaimTemplate allows customizing the persistent volume claim for the pod. | *[corev1.PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#persistentvolumeclaim-v1-core) | false |
 | customParameters | CustomParameters defines additional parameters to pass to the fdbserver process. | FoundationDBCustomParameters | false |
 
 [Back to TOC](#table-of-contents)
 
+## PublicIPSource
+
+PublicIPSource models options for how a pod gets its public IP.
+
+[Back to TOC](#table-of-contents)
+
 ## RequiredAddressSet
 
 RequiredAddressSet provides settings for which addresses we need to listen on.
@@ -364,9 +401,128 @@ RoutingConfig allows configuring routing to our pods, and services that sit in f
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
 | headlessService | Headless determines whether we want to run a headless service for the cluster. | *bool | false |
-| publicIPSource | PublicIPSource specifies what source a process should use to get its public IPs.  This supports the values `pod` and `service`. | *PublicIPSource | false |
+| publicIPSource | PublicIPSource specifies what source a process should use to get its public IPs.  This supports the values `pod` and `service`. | *[PublicIPSource](#publicipsource) | false |
 | podIPFamily | PodIPFamily tells the pod which family of IP addresses to use. You can use 4 to represent IPv4, and 6 to represent IPv6. This feature is only supported in FDB 7.0 or later, and requires dual-stack support in your Kubernetes environment. | *int | false |
 | useDNSInClusterFile | UseDNSInClusterFile determines whether to use DNS names rather than IP addresses to identify coordinators in the cluster file. NOTE: This is an experimental feature, and is not supported in the latest stable version of FoundationDB. | *bool | false |
 | dnsDomain | DNSDomain defines the cluster domain used in a DNS name generated for a service. The default is `cluster.local`. | *string | false |
 
 [Back to TOC](#table-of-contents)
+
+## FoundationDBCustomParameter
+
+FoundationDBCustomParameter defines a single custom knob
+
+[Back to TOC](#table-of-contents)
+
+## DataCenter
+
+DataCenter represents a data center in the region configuration
+
+| Field | Description | Scheme | Required |
+| ----- | ----------- | ------ | -------- |
+| id | The ID of the data center. This must match the dcid locality field. | string | false |
+| priority | The priority of this data center when we have to choose a location. Higher priorities are preferred over lower priorities. | int | false |
+| satellite | Satellite indicates whether the data center is serving as a satellite for the region. A value of 1 indicates that it is a satellite, and a value of 0 indicates that it is not a satellite. | int | false |
+
+[Back to TOC](#table-of-contents)
+
+## DatabaseConfiguration
+
+DatabaseConfiguration represents the configuration of the database
+
+| Field | Description | Scheme | Required |
+| ----- | ----------- | ------ | -------- |
+| redundancy_mode | RedundancyMode defines the core replication factor for the database. | [RedundancyMode](#redundancymode) | false |
+| storage_engine | StorageEngine defines the storage engine the database uses. | [StorageEngine](#storageengine) | false |
+| usable_regions | UsableRegions defines how many regions the database should store data in. | int | false |
+| regions | Regions defines the regions that the database can replicate in. | [][Region](#region) | false |
+| RoleCounts | RoleCounts defines how many processes the database should recruit for each role. | [RoleCounts](#rolecounts) | true |
+| VersionFlags | VersionFlags defines internal flags for testing new features in the database. | [VersionFlags](#versionflags) | true |
+
+[Back to TOC](#table-of-contents)
+
+## ProcessCounts
+
+ProcessCounts represents the number of processes we have for each valid process class.  If one of the counts in the spec is set to 0, we will infer the process count for that class from the role counts. If one of the counts in the spec is set to -1, we will not create any processes for that class. See GetProcessCountsWithDefaults for more information on the rules for inferring process counts.
+
+| Field | Description | Scheme | Required |
+| ----- | ----------- | ------ | -------- |
+| unset |  | int | false |
+| storage |  | int | false |
+| transaction |  | int | false |
+| resolution |  | int | false |
+| tester |  | int | false |
+| proxy |  | int | false |
+| commit_proxy |  | int | false |
+| grv_proxy |  | int | false |
+| master |  | int | false |
+| stateless |  | int | false |
+| log |  | int | false |
+| cluster_controller |  | int | false |
+| router |  | int | false |
+| fast_restore |  | int | false |
+| data_distributor |  | int | false |
+| coordinator |  | int | false |
+| ratekeeper |  | int | false |
+| storage_cache |  | int | false |
+| backup |  | int | false |
+
+[Back to TOC](#table-of-contents)
+
+## RedundancyMode
+
+RedundancyMode defines the core replication factor for the database
+
+[Back to TOC](#table-of-contents)
+
+## Region
+
+Region represents a region in the database configuration
+
+| Field | Description | Scheme | Required |
+| ----- | ----------- | ------ | -------- |
+| datacenters | The data centers in this region. | [][DataCenter](#datacenter) | false |
+| satellite_logs | The number of satellite logs that we should recruit. | int | false |
+| satellite_redundancy_mode | The replication strategy for satellite logs. | string | false |
+
+[Back to TOC](#table-of-contents)
+
+## RoleCounts
+
+RoleCounts represents the roles whose counts can be customized.
+
+| Field | Description | Scheme | Required |
+| ----- | ----------- | ------ | -------- |
+| storage |  | int | false |
+| logs |  | int | false |
+| proxies |  | int | false |
+| commit_proxies |  | int | false |
+| grv_proxies |  | int | false |
+| resolvers |  | int | false |
+| log_routers |  | int | false |
+| remote_logs |  | int | false |
+
+[Back to TOC](#table-of-contents)
+
+## StorageEngine
+
+StorageEngine defines the storage engine for the database
+
+[Back to TOC](#table-of-contents)
+
+## VersionFlags
+
+VersionFlags defines internal flags for new features in the database.
+
+| Field | Description | Scheme | Required |
+| ----- | ----------- | ------ | -------- |
+| log_spill |  | int | false |
+| log_version |  | int | false |
+
+[Back to TOC](#table-of-contents)
+
+## ProcessClass
+
+ProcessClass models the class of a pod
+
+[Back to TOC](#table-of-contents)
diff --git a/docs/manual/scaling.md b/docs/manual/scaling.md
index 80055c9f..53a07a4d 100644
--- a/docs/manual/scaling.md
+++ b/docs/manual/scaling.md
@@ -25,7 +25,7 @@ By default, the operator will provision processes with the following process typ
 
 1. `storage`. Equal to the storage count in the database configuration. If no storage count is provided, this will be `2*F+1`, where `F` is the desired fault tolerance. For a double replicated cluster, the desired fault tolerance is 1.
 2. `log`. Equal to the `F+max(logs, remote_logs)`. The `logs` and `remote_logs` here are the counts specified in the database configuration. By default, `logs` is set to 3 and `remote_logs` is set to either `-1` or `logs`.
-3. `stateless`. Equal to the sum of all other roles in the database configuration + `F`. Currently, this is `max(proxies+resolvers+4, log_routers)`. The `4` is for the master, cluster controller, data distributor, and ratekeeper processes. This may change in the future as we add more roles to the database. By default, `proxies` is set to 3, `resolvers` is set to 1, and `log_routers` is set to -1.
+3. `stateless`. Equal to the sum of all other roles in the database configuration + `F`. Currently, this is `max(proxies+resolvers+4, log_routers)`. The `4` is for the master, cluster controller, data distributor, and ratekeeper processes. This may change in the future as we add more roles to the database. By default, `proxies` is set to 3, `grv_proxies` is set 1, `commit_proxies` is set to 2, `resolvers` is set to 1, and `log_routers` is set to -1. If the version of FDB in the cluster is less than 7.0.0, the process counts will use the value of proxies set (or the default) and FDB will apply a ratio to how the individual proxy roles are distributed. If version of FDB is greater than 7.0.0 and the separated proxy counts are set while the old `proxies` are not, we will use `proxies=sum(grv_proxies + commit_proxies)`.
 
 You can also set a process count to -1 to tell the operator not to provision any processes of that type.
 
diff --git a/docs/restore_spec.md b/docs/restore_spec.md
index a5748ff7..9b008c58 100644
--- a/docs/restore_spec.md
+++ b/docs/restore_spec.md
@@ -1,9 +1,10 @@
-<br>
 # API Docs
+
 This Document documents the types introduced by the FoundationDB Operator to be consumed by users.
 > Note this document is generated from code comments. When contributing a change to this document please do so by changing the code comments.
 
 ## Table of Contents
+
 * [FoundationDBKeyRange](#foundationdbkeyrange)
 * [FoundationDBRestore](#foundationdbrestore)
 * [FoundationDBRestoreList](#foundationdbrestorelist)
@@ -27,7 +28,7 @@ FoundationDBRestore is the Schema for the foundationdbrestores API
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| metadata |  | [metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta) | false |
+| metadata |  | [metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta) | false |
 | spec |  | [FoundationDBRestoreSpec](#foundationdbrestorespec) | false |
 | status |  | [FoundationDBRestoreStatus](#foundationdbrestorestatus) | false |
 
@@ -39,7 +40,7 @@ FoundationDBRestoreList contains a list of FoundationDBRestore objects
 
 | Field | Description | Scheme | Required |
 | ----- | ----------- | ------ | -------- |
-| metadata |  | [metav1.ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#listmeta-v1-meta) | false |
+| metadata |  | [metav1.ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#listmeta-v1-meta) | false |
 | items |  | [][FoundationDBRestore](#foundationdbrestore) | true |
 
 [Back to TOC](#table-of-contents)
@@ -66,3 +67,9 @@ FoundationDBRestoreStatus describes the current status of the restore for a clus
 | running | Running describes whether the restore is currently running. | bool | false |
 
 [Back to TOC](#table-of-contents)
+
+## FoundationDBCustomParameter
+
+FoundationDBCustomParameter defines a single custom knob
+
+[Back to TOC](#table-of-contents)
diff --git a/fdbclient/admin_client.go b/fdbclient/admin_client.go
index d5eb4288..e5d56871 100644
--- a/fdbclient/admin_client.go
+++ b/fdbclient/admin_client.go
@@ -255,8 +255,8 @@ func (client *cliAdminClient) GetStatus() (*fdbv1beta2.FoundationDBStatus, error
 }
 
 // ConfigureDatabase sets the database configuration
-func (client *cliAdminClient) ConfigureDatabase(configuration fdbv1beta2.DatabaseConfiguration, newDatabase bool) error {
-	configurationString, err := configuration.GetConfigurationString()
+func (client *cliAdminClient) ConfigureDatabase(configuration fdbv1beta2.DatabaseConfiguration, newDatabase bool, version string) error {
+	configurationString, err := configuration.GetConfigurationString(version)
 	if err != nil {
 		return err
 	}
diff --git a/helm/fdb-operator/values.yaml b/helm/fdb-operator/values.yaml
index 07ba0fb0..381b7c4b 100644
--- a/helm/fdb-operator/values.yaml
+++ b/helm/fdb-operator/values.yaml
@@ -1,7 +1,7 @@
 ---
 image:
   repository: foundationdb/fdb-kubernetes-operator
-  tag: v1.0.0
+  tag: v1.1.0
   pullPolicy: IfNotPresent
 
 initContainers:
diff --git a/kubectl-fdb/Readme.md b/kubectl-fdb/Readme.md
index 0f5f0ee5..9b1bd82b 100644
--- a/kubectl-fdb/Readme.md
+++ b/kubectl-fdb/Readme.md
@@ -9,9 +9,10 @@ Install from release:
 
 ```bash
 pushd $TMPDIR
-OS=macos
+OS=$(uname)
+ARCH="x86_64"
 VERSION="$(curl -s "https://api.github.com/repos/FoundationDB/fdb-kubernetes-operator/releases/latest" | jq -r '.tag_name')"
-curl -sLo kubectl-fdb "https://github.com/FoundationDB/fdb-kubernetes-operator/releases/download/${VERSION}/kubectl-fdb-${VERSION}-${OS}"
+curl -sLo kubectl-fdb "https://github.com/FoundationDB/fdb-kubernetes-operator/releases/download/${VERSION}/kubectl-fdb_${VERSION}_${OS}_${ARCH}"
 chmod +x kubectl-fdb
 sudo mv ./kubectl-fdb /usr/local/bin
 popd
@@ -22,7 +23,7 @@ In order to install the latest version from the source code run:
 ```bash
 make plugin
 # move the binary into your path
-export PATH="$PATH:$(pwd)/bin" 
+export PATH="${PATH}:$(pwd)/dist/kubectl-fdb_$(go env GOHOSTOS)_$(go env GOARCH)"
 ```
 
 ## Usage
diff --git a/kubectl-fdb/cmd/configuration.go b/kubectl-fdb/cmd/configuration.go
index 9c51a3af..126a59d0 100644
--- a/kubectl-fdb/cmd/configuration.go
+++ b/kubectl-fdb/cmd/configuration.go
@@ -97,5 +97,5 @@ func getConfigurationString(kubeClient client.Client, clusterName string, namesp
 		config = config.FailOver()
 	}
 
-	return config.GetConfigurationString()
+	return config.GetConfigurationString(cluster.Spec.Version)
 }
diff --git a/pkg/fdbadminclient/admin_client.go b/pkg/fdbadminclient/admin_client.go
index cfd14708..e7825096 100644
--- a/pkg/fdbadminclient/admin_client.go
+++ b/pkg/fdbadminclient/admin_client.go
@@ -31,7 +31,7 @@ type AdminClient interface {
 	GetStatus() (*fdbv1beta2.FoundationDBStatus, error)
 
 	// ConfigureDatabase sets the database configuration
-	ConfigureDatabase(configuration fdbv1beta2.DatabaseConfiguration, newDatabase bool) error
+	ConfigureDatabase(configuration fdbv1beta2.DatabaseConfiguration, newDatabase bool, version string) error
 
 	// ExcludeProcesses starts evacuating processes so that they can be removed
 	// from the database.


Test patch:
diff --git a/api/v1beta2/foundationdb_status_test.go b/api/v1beta2/foundationdb_status_test.go
index 27e42e0c..45ecbac3 100644
--- a/api/v1beta2/foundationdb_status_test.go
+++ b/api/v1beta2/foundationdb_status_test.go
@@ -455,4 +455,330 @@ var _ = Describe("FoundationDBStatus", func() {
 			}))
 		})
 	})
+
+	When("parsing the status json with a 7.1.0-rc1 cluster", func() {
+		status := FoundationDBStatusClusterInfo{
+			DatabaseConfiguration: DatabaseConfiguration{
+				RedundancyMode: "double",
+				StorageEngine:  "ssd-2",
+				UsableRegions:  1,
+				Regions:        nil,
+				RoleCounts:     RoleCounts{Storage: 0, Logs: 3, Proxies: 3, CommitProxies: 2, GrvProxies: 1, Resolvers: 1, LogRouters: -1, RemoteLogs: -1},
+				VersionFlags:   VersionFlags{LogSpill: 2, LogVersion: 0},
+			},
+			Processes: map[string]FoundationDBStatusProcessInfo{
+				"eb48ada3a682e86363f06aa89e1041fa": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.18.254"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassStorage,
+					CommandLine:  "/usr/bin/fdbserver --class=storage --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.18.254:4501 --locality_instance_id=storage-1 --locality_machineid=test-cluster-storage-1 --locality_zoneid=test-cluster-storage-1 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.18.254:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"instance_id": "storage-1",
+						"machineid":   "test-cluster-storage-1",
+						"processid":   "eb48ada3a682e86363f06aa89e1041fa",
+						"zoneid":      "test-cluster-storage-1",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.0026,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: "coordinator"},
+						{Role: "grv_proxy"},
+						{Role: "storage"},
+					},
+				},
+				"eab0db1aa7aae81a50ca97e9814a1b7d": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.18.253"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassStorage,
+					CommandLine:  "/usr/bin/fdbserver --class=storage --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.18.253:4501 --locality_instance_id=storage-3 --locality_machineid=test-cluster-storage-3 --locality_zoneid=test-cluster-storage-3 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.18.253:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"instance_id": "storage-3",
+						"machineid":   "test-cluster-storage-3",
+						"processid":   "eab0db1aa7aae81a50ca97e9814a1b7d",
+						"zoneid":      "test-cluster-storage-3",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.0031,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: "coordinator"},
+						{Role: string(ProcessClassStorage)},
+						{Role: "resolver"},
+					},
+				},
+				"f483247d4d5f279ef02c549680cbde64": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.19.0"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassStorage,
+					CommandLine:  "/usr/bin/fdbserver --class=storage --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.0:4501 --locality_instance_id=storage-2 --locality_machineid=test-cluster-storage-2 --locality_zoneid=test-cluster-storage-2 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.0:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"instance_id": "storage-2",
+						"machineid":   "test-cluster-storage-2",
+						"processid":   "f483247d4d5f279ef02c549680cbde64",
+						"zoneid":      "test-cluster-storage-2",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.0029,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: "coordinator"},
+						{Role: "commit_proxy"},
+						{Role: "storage"},
+					},
+				},
+				"f6e0f7fd80da429d20329ad95d793ca3": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.19.1"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassLog,
+					CommandLine:  "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.1:4501 --locality_instance_id=log-1 --locality_machineid=test-cluster-log-1 --locality_zoneid=test-cluster-log-1 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.1:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"machineid":   "test-cluster-log-1",
+						"processid":   "f6e0f7fd80da429d20329ad95d793ca3",
+						"zoneid":      "test-cluster-log-1",
+						"instance_id": "log-1",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.0027,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: "master"},
+						{Role: "data_distributor"},
+						{Role: "ratekeeper"},
+					},
+				},
+				"f75644abdf1b06c803b5c3c124fdd0a0": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.18.255"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassClusterController,
+					CommandLine:  "/usr/bin/fdbserver --class=cluster_controller --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.18.255:4501 --locality_instance_id=cluster_controller-1 --locality_machineid=test-cluster-cluster-controller-1 --locality_zoneid=test-cluster-cluster-controller-1 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.18.255:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"processid":   "f75644abdf1b06c803b5c3c124fdd0a0",
+						"zoneid":      "test-cluster-cluster-controller-1",
+						"instance_id": "cluster_controller-1",
+						"machineid":   "test-cluster-cluster-controller-1",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.0029,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: string(ProcessClassClusterController)},
+					},
+				},
+				"105bf6c041f8ec315d03e889c2746ecf": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.19.2"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassLog,
+					CommandLine:  "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.2:4501 --locality_instance_id=log-3 --locality_machineid=test-cluster-log-3 --locality_zoneid=test-cluster-log-3 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.2:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"instance_id": "log-3",
+						"machineid":   "test-cluster-log-3",
+						"processid":   "105bf6c041f8ec315d03e889c2746ecf",
+						"zoneid":      "test-cluster-log-3",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.0029,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: "log"},
+					},
+				},
+				"78c1c84af4481f0df628d40358f0930a": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.19.4"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassLog,
+					CommandLine:  "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.4:4501 --locality_instance_id=log-2 --locality_machineid=test-cluster-log-2 --locality_zoneid=test-cluster-log-2 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.4:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"machineid":   "test-cluster-log-2",
+						"processid":   "78c1c84af4481f0df628d40358f0930a",
+						"zoneid":      "test-cluster-log-2",
+						"instance_id": "log-2",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.003,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: "log"},
+					},
+				},
+				"83084479b50c9c3a09b0286297be3796": {
+					Address: ProcessAddress{
+						IPAddress: net.ParseIP("10.1.19.3"),
+						Port:      4501,
+					},
+					ProcessClass: ProcessClassLog,
+					CommandLine:  "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.3:4501 --locality_instance_id=log-4 --locality_machineid=test-cluster-log-4 --locality_zoneid=test-cluster-log-4 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.3:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+					Excluded:     false,
+					Locality: map[string]string{
+						"instance_id": "log-4",
+						"machineid":   "test-cluster-log-4",
+						"processid":   "83084479b50c9c3a09b0286297be3796",
+						"zoneid":      "test-cluster-log-4",
+					},
+					Version:       "7.1.0-rc1",
+					UptimeSeconds: 85.0027,
+					Roles: []FoundationDBStatusProcessRoleInfo{
+						{Role: "log"},
+					},
+				},
+			},
+			Data: FoundationDBStatusDataStatistics{
+				KVBytes:    0,
+				MovingData: FoundationDBStatusMovingData{HighestPriority: 0, InFlightBytes: 0, InQueueBytes: 0},
+				State:      FoundationDBStatusDataState{Description: "", Healthy: true, Name: "healthy"},
+			},
+			FullReplication: true,
+			Clients: FoundationDBStatusClusterClientInfo{
+				Count: 8,
+				SupportedVersions: []FoundationDBStatusSupportedVersion{
+					{
+						ClientVersion: "6.2.30",
+						ConnectedClients: []FoundationDBStatusConnectedClient{
+							{
+								Address:  "10.1.18.249:34874",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:49078",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:51834",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+						},
+						MaxProtocolClients: nil,
+						ProtocolVersion:    "fdb00b062010001",
+						SourceVersion:      "c1acf5fc16a522b0f53b27874c88e21f5d34b251",
+					},
+					{
+						ClientVersion: "6.3.10",
+						ConnectedClients: []FoundationDBStatusConnectedClient{
+							{
+								Address:  "10.1.18.249:34874",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:49078",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:51834",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+						},
+						MaxProtocolClients: nil,
+						ProtocolVersion:    "fdb00b063010001",
+						SourceVersion:      "a461b9c93be19f846c2c41d9de455f968b53fd6d",
+					},
+					{
+						ClientVersion: "7.1.0-rc1",
+						ConnectedClients: []FoundationDBStatusConnectedClient{
+							{
+								Address:  "10.1.18.249:34874",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:35022",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:35642",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:49078",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:49230",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:51834",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:51920",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:52610",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+						},
+						MaxProtocolClients: []FoundationDBStatusConnectedClient{
+							{
+								Address:  "10.1.18.249:34874",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:35022",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:35642",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:49078",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:49230",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:51834",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:51920",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+							{
+								Address:  "10.1.18.249:52610",
+								LogGroup: "fdb-kubernetes-operator",
+							},
+						},
+						ProtocolVersion: "fdb00b071010000",
+						SourceVersion:   "079de5ba57f85e0abb9117e9378bb0b135a3da12",
+					},
+				},
+			},
+			Layers: FoundationDBStatusLayerInfo{
+				Backup: FoundationDBStatusBackupInfo{Paused: false, Tags: nil},
+				Error:  "",
+			},
+			FaultTolerance: FaultTolerance{
+				MaxZoneFailuresWithoutLosingData:         1,
+				MaxZoneFailuresWithoutLosingAvailability: 1,
+			},
+		}
+
+		It("should parse all values correctly", func() {
+			statusFile, err := os.OpenFile(filepath.Join("testdata", "fdb_status_7_1_rc1.json"), os.O_RDONLY, os.ModePerm)
+			Expect(err).NotTo(HaveOccurred())
+			defer statusFile.Close()
+			statusDecoder := json.NewDecoder(statusFile)
+			statusParsed := FoundationDBStatus{}
+			err = statusDecoder.Decode(&statusParsed)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(statusParsed.Cluster).To(Equal(status))
+		})
+	})
 })
diff --git a/api/v1beta2/foundationdb_version_test.go b/api/v1beta2/foundationdb_version_test.go
index 36f68465..46c95adc 100644
--- a/api/v1beta2/foundationdb_version_test.go
+++ b/api/v1beta2/foundationdb_version_test.go
@@ -50,6 +50,7 @@ var _ = Describe("[api] FDBVersion", func() {
 			version, err := ParseFdbVersion("6.2.11")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(version).To(Equal(Version{Major: 6, Minor: 2, Patch: 11}))
+			Expect(version.HasSeparatedProxies()).To(BeFalse())
 
 			version, err = ParseFdbVersion("prerelease-6.2.11")
 			Expect(err).NotTo(HaveOccurred())
@@ -59,6 +60,11 @@ var _ = Describe("[api] FDBVersion", func() {
 			Expect(err).NotTo(HaveOccurred())
 			Expect(version).To(Equal(Version{Major: 6, Minor: 2, Patch: 11, ReleaseCandidate: 0}))
 
+			version, err = ParseFdbVersion("7.0.0")
+			Expect(err).NotTo(HaveOccurred())
+			Expect(version).To(Equal(Version{Major: 7, Minor: 0, Patch: 0, ReleaseCandidate: 0}))
+			Expect(version.HasSeparatedProxies()).To(BeTrue())
+
 			version, err = ParseFdbVersion("7.0.0-rc1")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(version).To(Equal(Version{Major: 7, Minor: 0, Patch: 0, ReleaseCandidate: 1}))
@@ -66,6 +72,7 @@ var _ = Describe("[api] FDBVersion", func() {
 			version, err = ParseFdbVersion("7.1.0-rc39")
 			Expect(err).NotTo(HaveOccurred())
 			Expect(version).To(Equal(Version{Major: 7, Minor: 1, Patch: 0, ReleaseCandidate: 39}))
+			Expect(version.HasSeparatedProxies()).To(BeTrue())
 
 			_, err = ParseFdbVersion("6.2")
 			Expect(err).To(HaveOccurred())
diff --git a/api/v1beta2/foundationdbcluster_types_test.go b/api/v1beta2/foundationdbcluster_types_test.go
index c7af7856..a355006c 100644
--- a/api/v1beta2/foundationdbcluster_types_test.go
+++ b/api/v1beta2/foundationdbcluster_types_test.go
@@ -56,38 +56,46 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 
 			counts := cluster.GetRoleCountsWithDefaults()
 			Expect(counts).To(Equal(RoleCounts{
-				Storage:    3,
-				Logs:       3,
-				Proxies:    3,
-				Resolvers:  1,
-				RemoteLogs: -1,
-				LogRouters: -1,
+				Storage:       3,
+				Logs:          3,
+				Proxies:       3,
+				CommitProxies: 2,
+				GrvProxies:    1,
+				Resolvers:     1,
+				RemoteLogs:    -1,
+				LogRouters:    -1,
 			}))
 			Expect(counts.Map()).To(Equal(map[ProcessClass]int{
-				"logs":        3,
-				"proxies":     3,
-				"resolvers":   1,
-				"remote_logs": -1,
-				"log_routers": -1,
+				"logs":           3,
+				"proxies":        3,
+				"resolvers":      1,
+				"remote_logs":    -1,
+				"log_routers":    -1,
+				"commit_proxies": 2,
+				"grv_proxies":    1,
 			}))
 			Expect(cluster.Spec.DatabaseConfiguration.RoleCounts).To(Equal(RoleCounts{}))
 
 			cluster.Spec.DatabaseConfiguration.UsableRegions = 2
 			counts = cluster.GetRoleCountsWithDefaults()
 			Expect(counts).To(Equal(RoleCounts{
-				Storage:    3,
-				Logs:       3,
-				Proxies:    3,
-				Resolvers:  1,
-				RemoteLogs: 3,
-				LogRouters: 3,
+				Storage:       3,
+				Logs:          3,
+				CommitProxies: 2,
+				GrvProxies:    1,
+				Proxies:       3,
+				Resolvers:     1,
+				RemoteLogs:    3,
+				LogRouters:    3,
 			}))
 			Expect(counts.Map()).To(Equal(map[ProcessClass]int{
-				"logs":        3,
-				"proxies":     3,
-				"resolvers":   1,
-				"remote_logs": 3,
-				"log_routers": 3,
+				"logs":           3,
+				"proxies":        3,
+				"resolvers":      1,
+				"remote_logs":    3,
+				"log_routers":    3,
+				"commit_proxies": 2,
+				"grv_proxies":    1,
 			}))
 
 			cluster.Spec.DatabaseConfiguration.RoleCounts = RoleCounts{
@@ -96,12 +104,14 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 
 			counts = cluster.GetRoleCountsWithDefaults()
 			Expect(counts).To(Equal(RoleCounts{
-				Storage:    5,
-				Logs:       3,
-				Proxies:    3,
-				Resolvers:  1,
-				RemoteLogs: 3,
-				LogRouters: 3,
+				Storage:       5,
+				Logs:          3,
+				Proxies:       3,
+				GrvProxies:    1,
+				CommitProxies: 2,
+				Resolvers:     1,
+				RemoteLogs:    3,
+				LogRouters:    3,
 			}))
 
 			cluster.Spec.DatabaseConfiguration.RoleCounts = RoleCounts{
@@ -109,12 +119,14 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 			}
 			counts = cluster.GetRoleCountsWithDefaults()
 			Expect(counts).To(Equal(RoleCounts{
-				Storage:    3,
-				Logs:       8,
-				Proxies:    3,
-				Resolvers:  1,
-				RemoteLogs: 8,
-				LogRouters: 8,
+				Storage:       3,
+				Logs:          8,
+				CommitProxies: 2,
+				GrvProxies:    1,
+				Proxies:       3,
+				Resolvers:     1,
+				RemoteLogs:    8,
+				LogRouters:    8,
 			}))
 
 			cluster.Spec.DatabaseConfiguration.RoleCounts = RoleCounts{
@@ -124,12 +136,14 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 			}
 			counts = cluster.GetRoleCountsWithDefaults()
 			Expect(counts).To(Equal(RoleCounts{
-				Storage:    3,
-				Logs:       4,
-				Proxies:    3,
-				Resolvers:  1,
-				RemoteLogs: 5,
-				LogRouters: 6,
+				Storage:       3,
+				Logs:          4,
+				Proxies:       3,
+				GrvProxies:    1,
+				CommitProxies: 2,
+				Resolvers:     1,
+				RemoteLogs:    5,
+				LogRouters:    6,
 			}))
 		})
 	})
@@ -146,10 +160,12 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 					DatabaseConfiguration: DatabaseConfiguration{
 						RedundancyMode: RedundancyModeDouble,
 						RoleCounts: RoleCounts{
-							Storage:   5,
-							Logs:      3,
-							Proxies:   3,
-							Resolvers: 1,
+							Storage:       5,
+							Logs:          3,
+							Proxies:       3,
+							GrvProxies:    4,
+							CommitProxies: 12,
+							Resolvers:     1,
 						},
 					},
 				},
@@ -208,6 +224,15 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 				Log:       5,
 				Stateless: 9,
 			}))
+
+			cluster.Spec.Version = "7.1.0-rc2"
+			counts, err = cluster.GetProcessCountsWithDefaults()
+			Expect(err).NotTo(HaveOccurred())
+			Expect(counts).To(Equal(ProcessCounts{
+				Storage:   5,
+				Log:       5,
+				Stateless: 22,
+			}))
 		})
 	})
 
@@ -566,11 +591,13 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 				StorageEngine:  "ssd-2",
 				UsableRegions:  1,
 				RoleCounts: RoleCounts{
-					Logs:       4,
-					Proxies:    5,
-					Resolvers:  1,
-					LogRouters: -1,
-					RemoteLogs: -1,
+					Logs:          4,
+					Proxies:       5,
+					CommitProxies: 2,
+					GrvProxies:    1,
+					Resolvers:     1,
+					LogRouters:    -1,
+					RemoteLogs:    -1,
 				},
 			}))
 
@@ -581,27 +608,33 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 				StorageEngine:  "ssd-2",
 				UsableRegions:  1,
 				RoleCounts: RoleCounts{
-					Logs:       3,
-					Proxies:    3,
-					Resolvers:  1,
-					LogRouters: -1,
-					RemoteLogs: -1,
+					Logs:          3,
+					Proxies:       3,
+					CommitProxies: 2,
+					GrvProxies:    1,
+					Resolvers:     1,
+					LogRouters:    -1,
+					RemoteLogs:    -1,
 				},
 			}))
 		})
 	})
 
-	When("getting the  configuration string", func() {
+	When("getting the configuration string", func() {
 		It("should be parsed correctly", func() {
 			configuration := DatabaseConfiguration{
 				RedundancyMode: RedundancyModeDouble,
 				StorageEngine:  "ssd",
 				UsableRegions:  1,
 				RoleCounts: RoleCounts{
-					Logs: 5,
+					Logs:          5,
+					Proxies:       1,
+					CommitProxies: 2,
+					GrvProxies:    2,
 				},
 			}
-			Expect(configuration.GetConfigurationString()).To(Equal("double ssd usable_regions=1 logs=5 proxies=0 resolvers=0 log_routers=0 remote_logs=0 regions=[]"))
+			Expect(configuration.AreSeparatedProxiesConfigured()).To(BeFalse())
+			Expect(configuration.GetConfigurationString("6.3.24")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=1 regions=[]"))
 
 			configuration.Regions = []Region{{
 				DataCenters: []DataCenter{{
@@ -611,11 +644,62 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 				}},
 				SatelliteLogs: 2,
 			}}
-			Expect(configuration.GetConfigurationString()).To(Equal("double ssd usable_regions=1 logs=5 proxies=0 resolvers=0 log_routers=0 remote_logs=0 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"iad\\\",\\\"priority\\\":1}],\\\"satellite_logs\\\":2}]"))
+			Expect(configuration.GetConfigurationString("6.3.24")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=1 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"iad\\\",\\\"priority\\\":1}],\\\"satellite_logs\\\":2}]"))
 			configuration.Regions = nil
 
 			configuration.VersionFlags.LogSpill = 3
-			Expect(configuration.GetConfigurationString()).To(Equal("double ssd usable_regions=1 logs=5 proxies=0 resolvers=0 log_routers=0 remote_logs=0 log_spill:=3 regions=[]"))
+			Expect(configuration.GetConfigurationString("6.3.24")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=1 log_spill:=3 regions=[]"))
+
+			Expect(configuration.GetConfigurationString("7.0.0")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=1 log_spill:=3 regions=[]"))
+			Expect(configuration.GetConfigurationString("7.1.0-rc1")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=1 log_spill:=3 regions=[]"))
+		})
+
+		When("CommitProxies and GrvProxies are not configured", func() {
+			configuration := DatabaseConfiguration{
+				RedundancyMode: RedundancyModeDouble,
+				StorageEngine:  "ssd",
+				UsableRegions:  1,
+				RoleCounts: RoleCounts{
+					Logs:    5,
+					Proxies: 1,
+				},
+			}
+			It("should be parsed correctly", func() {
+				Expect(configuration.GetConfigurationString("6.3.24")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=1 regions=[]"))
+				Expect(configuration.GetConfigurationString("7.0.0")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=1 regions=[]"))
+			})
+
+			It("should have no proxies configured", func() {
+				version, _ := ParseFdbVersion("7.0.0")
+				Expect(configuration.AreSeparatedProxiesConfigured()).To(BeFalse())
+				Expect(configuration.GetProxiesString(version)).To(Equal(" proxies=1"))
+			})
+		})
+
+		When("CommitProxies and GrvProxies are configured but not proxies", func() {
+			configuration := DatabaseConfiguration{
+				RedundancyMode: RedundancyModeDouble,
+				StorageEngine:  "ssd",
+				UsableRegions:  1,
+				RoleCounts: RoleCounts{
+					Logs:          5,
+					CommitProxies: 2,
+					GrvProxies:    1,
+				},
+			}
+			It("should have old proxies configuration with version FDB < 7.0.0 ", func() {
+				version, _ := ParseFdbVersion("6.3.24")
+				Expect(configuration.AreSeparatedProxiesConfigured()).To(BeTrue())
+				Expect(configuration.GetProxiesString(version)).To(Equal(" proxies=3"))
+				Expect(configuration.GetConfigurationString("6.3.24")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 proxies=3 regions=[]"))
+			})
+
+			It("should have separated proxies configured with FDB > 7.0.0", func() {
+				version, _ := ParseFdbVersion("7.0.0")
+				Expect(configuration.AreSeparatedProxiesConfigured()).To(BeTrue())
+				Expect(configuration.GetProxiesString(version)).To(Equal(" commit_proxies=2 grv_proxies=1"))
+				Expect(configuration.GetConfigurationString("7.0.0")).To(Equal("double ssd usable_regions=1 logs=5 resolvers=0 log_routers=0 remote_logs=0 commit_proxies=2 grv_proxies=1 regions=[]"))
+			})
 		})
 	})
 
@@ -807,7 +891,7 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 		})
 	})
 
-	When("changing tto fearless dr without initial regions", func() {
+	When("changing to fearless dr without initial regions", func() {
 		It("should return the fearless config", func() {
 			currentConfig := DatabaseConfiguration{
 				RedundancyMode: RedundancyModeDouble,
@@ -2450,11 +2534,13 @@ var _ = Describe("[api] FoundationDBCluster", func() {
 							StorageEngine:  "ssd-2",
 							UsableRegions:  1,
 							RoleCounts: RoleCounts{
-								Logs:       3,
-								Proxies:    3,
-								Resolvers:  1,
-								LogRouters: -1,
-								RemoteLogs: -1,
+								Logs:          3,
+								Proxies:       3,
+								GrvProxies:    1,
+								CommitProxies: 2,
+								Resolvers:     1,
+								LogRouters:    -1,
+								RemoteLogs:    -1,
 							},
 						},
 						Generations: ClusterGenerationStatus{
diff --git a/api/v1beta2/testdata/fdb_status_7_1_rc1.json b/api/v1beta2/testdata/fdb_status_7_1_rc1.json
new file mode 100644
index 00000000..d78bf4ce
--- /dev/null
+++ b/api/v1beta2/testdata/fdb_status_7_1_rc1.json
@@ -0,0 +1,1649 @@
+{
+    "client" : {
+        "cluster_file" : {
+            "path" : "/var/dynamic-conf/fdb.cluster",
+            "up_to_date" : true
+        },
+        "coordinators" : {
+            "coordinators" : [
+                {
+                    "address" : "10.1.18.253:4501",
+                    "protocol" : "0fdb00b071010000",
+                    "reachable" : true
+                },
+                {
+                    "address" : "10.1.18.254:4501",
+                    "protocol" : "0fdb00b071010000",
+                    "reachable" : true
+                },
+                {
+                    "address" : "10.1.19.0:4501",
+                    "protocol" : "0fdb00b071010000",
+                    "reachable" : true
+                }
+            ],
+            "quorum_reachable" : true
+        },
+        "database_status" : {
+            "available" : true,
+            "healthy" : true
+        },
+        "messages" : [
+        ],
+        "timestamp" : 1646933244
+    },
+    "cluster" : {
+        "active_primary_dc" : "",
+        "active_tss_count" : 0,
+        "bounce_impact" : {
+            "can_clean_bounce" : true
+        },
+        "clients" : {
+            "count" : 8,
+            "supported_versions" : [
+                {
+                    "client_version" : "6.2.30",
+                    "connected_clients" : [
+                        {
+                            "address" : "10.1.18.249:34874",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:49078",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:51834",
+                            "log_group" : "fdb-kubernetes-operator"
+                        }
+                    ],
+                    "count" : 3,
+                    "protocol_version" : "fdb00b062010001",
+                    "source_version" : "c1acf5fc16a522b0f53b27874c88e21f5d34b251"
+                },
+                {
+                    "client_version" : "6.3.10",
+                    "connected_clients" : [
+                        {
+                            "address" : "10.1.18.249:34874",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:49078",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:51834",
+                            "log_group" : "fdb-kubernetes-operator"
+                        }
+                    ],
+                    "count" : 3,
+                    "protocol_version" : "fdb00b063010001",
+                    "source_version" : "a461b9c93be19f846c2c41d9de455f968b53fd6d"
+                },
+                {
+                    "client_version" : "7.1.0-rc1",
+                    "connected_clients" : [
+                        {
+                            "address" : "10.1.18.249:34874",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:35022",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:35642",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:49078",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:49230",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:51834",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:51920",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:52610",
+                            "log_group" : "fdb-kubernetes-operator"
+                        }
+                    ],
+                    "count" : 8,
+                    "max_protocol_clients" : [
+                        {
+                            "address" : "10.1.18.249:34874",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:35022",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:35642",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:49078",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:49230",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:51834",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:51920",
+                            "log_group" : "fdb-kubernetes-operator"
+                        },
+                        {
+                            "address" : "10.1.18.249:52610",
+                            "log_group" : "fdb-kubernetes-operator"
+                        }
+                    ],
+                    "max_protocol_count" : 8,
+                    "protocol_version" : "fdb00b071010000",
+                    "source_version" : "079de5ba57f85e0abb9117e9378bb0b135a3da12"
+                }
+            ]
+        },
+        "cluster_controller_timestamp" : 1646933244,
+        "configuration" : {
+            "backup_worker_enabled" : 0,
+            "commit_proxies" : 2,
+            "coordinators_count" : 3,
+            "excluded_servers" : [
+            ],
+            "grv_proxies" : 1,
+            "log_routers" : -1,
+            "log_spill" : 2,
+            "logs" : 3,
+            "perpetual_storage_wiggle" : 0,
+            "perpetual_storage_wiggle_locality" : "0",
+            "proxies" : 3,
+            "redundancy_mode" : "double",
+            "remote_logs" : -1,
+            "resolvers" : 1,
+            "storage_engine" : "ssd-2",
+            "storage_migration_type" : "disabled",
+            "usable_regions" : 1
+        },
+        "connection_string" : "test_cluster:aHeD9ocNXOUxi0dyzU3k7Bhg53SpyrBV@10.1.18.253:4501,10.1.18.254:4501,10.1.19.0:4501",
+        "data" : {
+            "average_partition_size_bytes" : 400000,
+            "least_operating_space_bytes_log_server" : 77427512760,
+            "least_operating_space_bytes_storage_server" : 77427513204,
+            "moving_data" : {
+                "highest_priority" : 0,
+                "in_flight_bytes" : 0,
+                "in_queue_bytes" : 0,
+                "total_written_bytes" : 0
+            },
+            "partitions_count" : 1,
+            "state" : {
+                "healthy" : true,
+                "min_replicas_remaining" : 2,
+                "name" : "healthy"
+            },
+            "system_kv_size_bytes" : 0,
+            "team_trackers" : [
+                {
+                    "in_flight_bytes" : 0,
+                    "primary" : true,
+                    "state" : {
+                        "healthy" : true,
+                        "min_replicas_remaining" : 2,
+                        "name" : "healthy"
+                    },
+                    "unhealthy_servers" : 0
+                }
+            ],
+            "total_disk_used_bytes" : 629203472,
+            "total_kv_size_bytes" : 0
+        },
+        "database_available" : true,
+        "database_lock_state" : {
+            "locked" : false
+        },
+        "datacenter_lag" : {
+            "seconds" : 0,
+            "versions" : 0
+        },
+        "degraded_processes" : 0,
+        "fault_tolerance" : {
+            "max_zone_failures_without_losing_availability" : 1,
+            "max_zone_failures_without_losing_data" : 1
+        },
+        "full_replication" : true,
+        "generation" : 2,
+        "incompatible_connections" : [
+        ],
+        "latency_probe" : {
+            "batch_priority_transaction_start_seconds" : 0.00241208,
+            "commit_seconds" : 0.0045864599999999997,
+            "immediate_priority_transaction_start_seconds" : 0.0022053699999999999,
+            "read_seconds" : 0.00039434399999999998,
+            "transaction_start_seconds" : 0.00389361
+        },
+        "layers" : {
+            "_valid" : true
+        },
+        "logs" : [
+            {
+                "begin_version" : 0,
+                "current" : true,
+                "epoch" : 2,
+                "log_fault_tolerance" : 1,
+                "log_interfaces" : [
+                    {
+                        "address" : "10.1.19.3:4501",
+                        "healthy" : true,
+                        "id" : "31754d1d7d8d6f05"
+                    },
+                    {
+                        "address" : "10.1.19.4:4501",
+                        "healthy" : true,
+                        "id" : "56cf105980ec2b07"
+                    },
+                    {
+                        "address" : "10.1.19.2:4501",
+                        "healthy" : true,
+                        "id" : "2c66a861b33b2697"
+                    }
+                ],
+                "log_replication_factor" : 2,
+                "log_write_anti_quorum" : 0,
+                "possibly_losing_data" : false
+            }
+        ],
+        "machines" : {
+            "test-cluster-cluster-controller-1" : {
+                "address" : "10.1.18.255",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.058885100000000003
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "cluster_controller-1",
+                    "machineid" : "test-cluster-cluster-controller-1",
+                    "processid" : "f75644abdf1b06c803b5c3c124fdd0a0",
+                    "zoneid" : "test-cluster-cluster-controller-1"
+                },
+                "machine_id" : "test-cluster-cluster-controller-1",
+                "memory" : {
+                    "committed_bytes" : 2285780992,
+                    "free_bytes" : 14505558016,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.21671900000000002
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.22023900000000002
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            },
+            "test-cluster-log-1" : {
+                "address" : "10.1.19.1",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.058623400000000006
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "log-1",
+                    "machineid" : "test-cluster-log-1",
+                    "processid" : "f6e0f7fd80da429d20329ad95d793ca3",
+                    "zoneid" : "test-cluster-log-1"
+                },
+                "machine_id" : "test-cluster-log-1",
+                "memory" : {
+                    "committed_bytes" : 2286039040,
+                    "free_bytes" : 14505299968,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.344115
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.26798900000000003
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            },
+            "test-cluster-log-2" : {
+                "address" : "10.1.19.4",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.058623400000000006
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "log-2",
+                    "machineid" : "test-cluster-log-2",
+                    "processid" : "78c1c84af4481f0df628d40358f0930a",
+                    "zoneid" : "test-cluster-log-2"
+                },
+                "machine_id" : "test-cluster-log-2",
+                "memory" : {
+                    "committed_bytes" : 2286039040,
+                    "free_bytes" : 14505299968,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.166773
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.103298
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            },
+            "test-cluster-log-3" : {
+                "address" : "10.1.19.2",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.058623400000000006
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "log-3",
+                    "machineid" : "test-cluster-log-3",
+                    "processid" : "105bf6c041f8ec315d03e889c2746ecf",
+                    "zoneid" : "test-cluster-log-3"
+                },
+                "machine_id" : "test-cluster-log-3",
+                "memory" : {
+                    "committed_bytes" : 2286039040,
+                    "free_bytes" : 14505299968,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.088260000000000005
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.085034600000000002
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            },
+            "test-cluster-log-4" : {
+                "address" : "10.1.19.3",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.058623400000000006
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "log-4",
+                    "machineid" : "test-cluster-log-4",
+                    "processid" : "83084479b50c9c3a09b0286297be3796",
+                    "zoneid" : "test-cluster-log-4"
+                },
+                "machine_id" : "test-cluster-log-4",
+                "memory" : {
+                    "committed_bytes" : 2286039040,
+                    "free_bytes" : 14505299968,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.091471200000000003
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.091644000000000003
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            },
+            "test-cluster-storage-1" : {
+                "address" : "10.1.18.254",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.058608
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "storage-1",
+                    "machineid" : "test-cluster-storage-1",
+                    "processid" : "eb48ada3a682e86363f06aa89e1041fa",
+                    "zoneid" : "test-cluster-storage-1"
+                },
+                "machine_id" : "test-cluster-storage-1",
+                "memory" : {
+                    "committed_bytes" : 2286297088,
+                    "free_bytes" : 14505041920,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.267594
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.36186400000000002
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            },
+            "test-cluster-storage-2" : {
+                "address" : "10.1.19.0",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.0583768
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "storage-2",
+                    "machineid" : "test-cluster-storage-2",
+                    "processid" : "f483247d4d5f279ef02c549680cbde64",
+                    "zoneid" : "test-cluster-storage-2"
+                },
+                "machine_id" : "test-cluster-storage-2",
+                "memory" : {
+                    "committed_bytes" : 2286297088,
+                    "free_bytes" : 14505041920,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.113719
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.14154
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            },
+            "test-cluster-storage-3" : {
+                "address" : "10.1.18.253",
+                "contributing_workers" : 1,
+                "cpu" : {
+                    "logical_core_utilization" : 0.058608200000000006
+                },
+                "excluded" : false,
+                "locality" : {
+                    "instance_id" : "storage-3",
+                    "machineid" : "test-cluster-storage-3",
+                    "processid" : "eab0db1aa7aae81a50ca97e9814a1b7d",
+                    "zoneid" : "test-cluster-storage-3"
+                },
+                "machine_id" : "test-cluster-storage-3",
+                "memory" : {
+                    "committed_bytes" : 2286297088,
+                    "free_bytes" : 14505041920,
+                    "total_bytes" : 16791339008
+                },
+                "network" : {
+                    "megabits_received" : {
+                        "hz" : 0.106423
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.12354800000000001
+                    },
+                    "tcp_segments_retransmitted" : {
+                        "hz" : 0
+                    }
+                }
+            }
+        },
+        "messages" : [
+        ],
+        "page_cache" : {
+            "log_hit_rate" : 1,
+            "storage_hit_rate" : 1
+        },
+        "processes" : {
+            "105bf6c041f8ec315d03e889c2746ecf" : {
+                "address" : "10.1.19.2:4501",
+                "class_source" : "command_line",
+                "class_type" : "log",
+                "command_line" : "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.2:4501 --locality_instance_id=log-3 --locality_machineid=test-cluster-log-3 --locality_zoneid=test-cluster-log-3 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.2:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.012726600000000001
+                },
+                "disk" : {
+                    "busy" : 0.0101993,
+                    "free_bytes" : 84178165760,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 19.598700000000001,
+                        "sectors" : 1600
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-log-3",
+                "locality" : {
+                    "instance_id" : "log-3",
+                    "machineid" : "test-cluster-log-3",
+                    "processid" : "105bf6c041f8ec315d03e889c2746ecf",
+                    "zoneid" : "test-cluster-log-3"
+                },
+                "machine_id" : "test-cluster-log-3",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 216772608
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0
+                    },
+                    "current_connections" : 5,
+                    "megabits_received" : {
+                        "hz" : 0.038947900000000001
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.054306900000000005
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "data_version" : 74805090,
+                        "durable_bytes" : {
+                            "counter" : 255,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "id" : "2c66a861b33b2697",
+                        "input_bytes" : {
+                            "counter" : 1512,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "kvstore_available_bytes" : 84178214912,
+                        "kvstore_free_bytes" : 84178214912,
+                        "kvstore_total_bytes" : 135012552704,
+                        "kvstore_used_bytes" : 104861752,
+                        "queue_disk_available_bytes" : 84178214912,
+                        "queue_disk_free_bytes" : 84178214912,
+                        "queue_disk_total_bytes" : 135012552704,
+                        "queue_disk_used_bytes" : 389120,
+                        "role" : "log"
+                    }
+                ],
+                "run_loop_busy" : 0.0081051000000000005,
+                "uptime_seconds" : 85.002899999999997,
+                "version" : "7.1.0-rc1"
+            },
+            "78c1c84af4481f0df628d40358f0930a" : {
+                "address" : "10.1.19.4:4501",
+                "class_source" : "command_line",
+                "class_type" : "log",
+                "command_line" : "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.4:4501 --locality_instance_id=log-2 --locality_machineid=test-cluster-log-2 --locality_zoneid=test-cluster-log-2 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.4:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.0137228
+                },
+                "disk" : {
+                    "busy" : 0.0101996,
+                    "free_bytes" : 84178165760,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 19.5991,
+                        "sectors" : 1600
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-log-2",
+                "locality" : {
+                    "instance_id" : "log-2",
+                    "machineid" : "test-cluster-log-2",
+                    "processid" : "78c1c84af4481f0df628d40358f0930a",
+                    "zoneid" : "test-cluster-log-2"
+                },
+                "machine_id" : "test-cluster-log-2",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 197763072
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0
+                    },
+                    "current_connections" : 6,
+                    "megabits_received" : {
+                        "hz" : 0.041451000000000002
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.058755800000000004
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "data_version" : 74805090,
+                        "durable_bytes" : {
+                            "counter" : 3264,
+                            "hz" : 20.3995,
+                            "roughness" : 100.999
+                        },
+                        "id" : "56cf105980ec2b07",
+                        "input_bytes" : {
+                            "counter" : 14551,
+                            "hz" : 51.198700000000002,
+                            "roughness" : 255
+                        },
+                        "kvstore_available_bytes" : 84178214912,
+                        "kvstore_free_bytes" : 84178214912,
+                        "kvstore_total_bytes" : 135012552704,
+                        "kvstore_used_bytes" : 104861752,
+                        "queue_disk_available_bytes" : 84178214912,
+                        "queue_disk_free_bytes" : 84178214912,
+                        "queue_disk_total_bytes" : 135012552704,
+                        "queue_disk_used_bytes" : 258048,
+                        "role" : "log"
+                    }
+                ],
+                "run_loop_busy" : 0.0088742700000000001,
+                "uptime_seconds" : 85.003,
+                "version" : "7.1.0-rc1"
+            },
+            "83084479b50c9c3a09b0286297be3796" : {
+                "address" : "10.1.19.3:4501",
+                "class_source" : "command_line",
+                "class_type" : "log",
+                "command_line" : "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.3:4501 --locality_instance_id=log-4 --locality_machineid=test-cluster-log-4 --locality_zoneid=test-cluster-log-4 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.3:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.0140474
+                },
+                "disk" : {
+                    "busy" : 0.0101996,
+                    "free_bytes" : 84178165760,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 19.5991,
+                        "sectors" : 1600
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-log-4",
+                "locality" : {
+                    "instance_id" : "log-4",
+                    "machineid" : "test-cluster-log-4",
+                    "processid" : "83084479b50c9c3a09b0286297be3796",
+                    "zoneid" : "test-cluster-log-4"
+                },
+                "machine_id" : "test-cluster-log-4",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 210481152
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0
+                    },
+                    "current_connections" : 6,
+                    "megabits_received" : {
+                        "hz" : 0.041207800000000003
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.058487000000000004
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "data_version" : 74805090,
+                        "durable_bytes" : {
+                            "counter" : 3315,
+                            "hz" : 20.399100000000001,
+                            "roughness" : 101
+                        },
+                        "id" : "31754d1d7d8d6f05",
+                        "input_bytes" : {
+                            "counter" : 15459,
+                            "hz" : 51.197800000000001,
+                            "roughness" : 255
+                        },
+                        "kvstore_available_bytes" : 84178202624,
+                        "kvstore_free_bytes" : 84178202624,
+                        "kvstore_total_bytes" : 135012552704,
+                        "kvstore_used_bytes" : 104861752,
+                        "queue_disk_available_bytes" : 84178202624,
+                        "queue_disk_free_bytes" : 84178202624,
+                        "queue_disk_total_bytes" : 135012552704,
+                        "queue_disk_used_bytes" : 258048,
+                        "role" : "log"
+                    }
+                ],
+                "run_loop_busy" : 0.0089497099999999979,
+                "uptime_seconds" : 85.002700000000004,
+                "version" : "7.1.0-rc1"
+            },
+            "eab0db1aa7aae81a50ca97e9814a1b7d" : {
+                "address" : "10.1.18.253:4501",
+                "class_source" : "command_line",
+                "class_type" : "storage",
+                "command_line" : "/usr/bin/fdbserver --class=storage --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.18.253:4501 --locality_instance_id=storage-3 --locality_machineid=test-cluster-storage-3 --locality_zoneid=test-cluster-storage-3 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.18.253:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.0126458
+                },
+                "disk" : {
+                    "busy" : 0.0097997299999999996,
+                    "free_bytes" : 84178145280,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 18.599499999999999,
+                        "sectors" : 1456
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-storage-3",
+                "locality" : {
+                    "instance_id" : "storage-3",
+                    "machineid" : "test-cluster-storage-3",
+                    "processid" : "eab0db1aa7aae81a50ca97e9814a1b7d",
+                    "zoneid" : "test-cluster-storage-3"
+                },
+                "machine_id" : "test-cluster-storage-3",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 196194304
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0.19999400000000001
+                    },
+                    "current_connections" : 9,
+                    "megabits_received" : {
+                        "hz" : 0.070506800000000008
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.094602100000000008
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "role" : "coordinator"
+                    },
+                    {
+                        "bytes_queried" : {
+                            "counter" : 226531,
+                            "hz" : 3388.3899999999999,
+                            "roughness" : 4366.4099999999999
+                        },
+                        "data_lag" : {
+                            "seconds" : 2.1227,
+                            "versions" : 2122697
+                        },
+                        "data_version" : 74608832,
+                        "durability_lag" : {
+                            "seconds" : 5,
+                            "versions" : 5000000
+                        },
+                        "durable_bytes" : {
+                            "counter" : 75858,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "durable_version" : 69608832,
+                        "fetched_versions" : {
+                            "counter" : 74608832,
+                            "hz" : 1647130.0000000002,
+                            "roughness" : 2866620
+                        },
+                        "fetches_from_logs" : {
+                            "counter" : 53,
+                            "hz" : 0.79995000000000005,
+                            "roughness" : 0.39221300000000003
+                        },
+                        "finished_queries" : {
+                            "counter" : 446,
+                            "hz" : 3.9997500000000001,
+                            "roughness" : 4.1554200000000003
+                        },
+                        "id" : "389c23d59a646e52",
+                        "input_bytes" : {
+                            "counter" : 77854,
+                            "hz" : 399.17500000000001,
+                            "roughness" : 1995
+                        },
+                        "keys_queried" : {
+                            "counter" : 1049,
+                            "hz" : 13.5992,
+                            "roughness" : 16.528400000000001
+                        },
+                        "kvstore_available_bytes" : 84178239488,
+                        "kvstore_free_bytes" : 84178239488,
+                        "kvstore_inline_keys" : 0,
+                        "kvstore_total_bytes" : 135012552704,
+                        "kvstore_total_nodes" : 0,
+                        "kvstore_total_size" : 0,
+                        "kvstore_used_bytes" : 104878232,
+                        "local_rate" : 100,
+                        "low_priority_queries" : {
+                            "counter" : 0,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "mutation_bytes" : {
+                            "counter" : 5972,
+                            "hz" : 18.7988,
+                            "roughness" : 93
+                        },
+                        "mutations" : {
+                            "counter" : 78,
+                            "hz" : 0.39997500000000002,
+                            "roughness" : 1
+                        },
+                        "query_queue_max" : 3,
+                        "read_latency_statistics" : {
+                            "count" : 334,
+                            "max" : 0.00058245699999999998,
+                            "mean" : 0.000121679,
+                            "median" : 0.00010228199999999999,
+                            "min" : 1.16825e-05,
+                            "p25" : 6.8187699999999998e-05,
+                            "p90" : 0.00023627299999999998,
+                            "p95" : 0.00031471299999999999,
+                            "p99" : 0.00038647699999999998,
+                            "p99.9" : 0.00048828099999999997
+                        },
+                        "role" : "storage",
+                        "storage_metadata" : {
+                            "created_time_datetime" : "Thu Mar 10 17:26:07 2022 +0000",
+                            "created_time_timestamp" : 1646933167898430464
+                        },
+                        "stored_bytes" : 0,
+                        "total_queries" : {
+                            "counter" : 446,
+                            "hz" : 3.9997500000000001,
+                            "roughness" : 4.1554200000000003
+                        }
+                    },
+                    {
+                        "id" : "dfd679875a386d06",
+                        "role" : "resolver"
+                    }
+                ],
+                "run_loop_busy" : 0.0080509299999999978,
+                "uptime_seconds" : 85.003100000000003,
+                "version" : "7.1.0-rc1"
+            },
+            "eb48ada3a682e86363f06aa89e1041fa" : {
+                "address" : "10.1.18.254:4501",
+                "class_source" : "command_line",
+                "class_type" : "storage",
+                "command_line" : "/usr/bin/fdbserver --class=storage --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.18.254:4501 --locality_instance_id=storage-1 --locality_machineid=test-cluster-storage-1 --locality_zoneid=test-cluster-storage-1 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.18.254:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.036252700000000006
+                },
+                "disk" : {
+                    "busy" : 0.0097997599999999994,
+                    "free_bytes" : 84178145280,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 18.599599999999999,
+                        "sectors" : 1456
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-storage-1",
+                "locality" : {
+                    "instance_id" : "storage-1",
+                    "machineid" : "test-cluster-storage-1",
+                    "processid" : "eb48ada3a682e86363f06aa89e1041fa",
+                    "zoneid" : "test-cluster-storage-1"
+                },
+                "machine_id" : "test-cluster-storage-1",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 189898752
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0.19999500000000001
+                    },
+                    "current_connections" : 9,
+                    "megabits_received" : {
+                        "hz" : 0.17158000000000001
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.224244
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "role" : "coordinator"
+                    },
+                    {
+                        "grv_latency_statistics" : {
+                            "batch" : {
+                                "count" : 6,
+                                "max" : 0.0047154399999999996,
+                                "mean" : 0.00133355,
+                                "median" : 0.00053143500000000002,
+                                "min" : 0.00045347199999999996,
+                                "p25" : 0.00045371099999999998,
+                                "p90" : 0.0013067700000000001,
+                                "p95" : 0.0013067700000000001,
+                                "p99" : 0.0013067700000000001,
+                                "p99.9" : 0.0013067700000000001
+                            },
+                            "default" : {
+                                "count" : 225,
+                                "max" : 0.089440599999999995,
+                                "mean" : 0.0020094599999999998,
+                                "median" : 0.00062560999999999997,
+                                "min" : 0.00034069999999999999,
+                                "p25" : 0.00053405800000000002,
+                                "p90" : 0.0020797300000000001,
+                                "p95" : 0.00669289,
+                                "p99" : 0.010715200000000001,
+                                "p99.9" : 0.088694600000000012
+                            }
+                        },
+                        "id" : "0de7f5c5e549cad1",
+                        "role" : "grv_proxy"
+                    },
+                    {
+                        "bytes_queried" : {
+                            "counter" : 223948,
+                            "hz" : 2430.7199999999998,
+                            "roughness" : 3618.48
+                        },
+                        "data_lag" : {
+                            "seconds" : 0.19625800000000002,
+                            "versions" : 196258
+                        },
+                        "data_version" : 74805090,
+                        "durability_lag" : {
+                            "seconds" : 5.1962599999999997,
+                            "versions" : 5196258
+                        },
+                        "durable_bytes" : {
+                            "counter" : 75858,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "durable_version" : 69608832,
+                        "fetched_versions" : {
+                            "counter" : 74805090,
+                            "hz" : 1686420,
+                            "roughness" : 2759180
+                        },
+                        "fetches_from_logs" : {
+                            "counter" : 54,
+                            "hz" : 0.99996600000000002,
+                            "roughness" : 0.63605800000000001
+                        },
+                        "finished_queries" : {
+                            "counter" : 426,
+                            "hz" : 4.5998400000000004,
+                            "roughness" : 4.3348199999999997
+                        },
+                        "id" : "9941616400759d37",
+                        "input_bytes" : {
+                            "counter" : 77854,
+                            "hz" : 399.18700000000001,
+                            "roughness" : 1995
+                        },
+                        "keys_queried" : {
+                            "counter" : 1051,
+                            "hz" : 12.1996,
+                            "roughness" : 17.165900000000001
+                        },
+                        "kvstore_available_bytes" : 84178223104,
+                        "kvstore_free_bytes" : 84178223104,
+                        "kvstore_inline_keys" : 0,
+                        "kvstore_total_bytes" : 135012552704,
+                        "kvstore_total_nodes" : 0,
+                        "kvstore_total_size" : 0,
+                        "kvstore_used_bytes" : 104878232,
+                        "local_rate" : 100,
+                        "low_priority_queries" : {
+                            "counter" : 0,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "mutation_bytes" : {
+                            "counter" : 5972,
+                            "hz" : 18.799399999999999,
+                            "roughness" : 93
+                        },
+                        "mutations" : {
+                            "counter" : 78,
+                            "hz" : 0.39998600000000001,
+                            "roughness" : 1
+                        },
+                        "query_queue_max" : 3,
+                        "read_latency_statistics" : {
+                            "count" : 297,
+                            "max" : 0.078662399999999993,
+                            "mean" : 0.00067559199999999992,
+                            "median" : 0.00011682499999999999,
+                            "min" : 1.3828300000000003e-05,
+                            "p25" : 7.9631800000000012e-05,
+                            "p90" : 0.00028634099999999996,
+                            "p95" : 0.000379324,
+                            "p99" : 0.00071144100000000005,
+                            "p99.9" : 0.078609699999999991
+                        },
+                        "role" : "storage",
+                        "storage_metadata" : {
+                            "created_time_datetime" : "Thu Mar 10 17:26:07 2022 +0000",
+                            "created_time_timestamp" : 1646933167898430464
+                        },
+                        "stored_bytes" : 0,
+                        "total_queries" : {
+                            "counter" : 426,
+                            "hz" : 4.5998400000000004,
+                            "roughness" : 4.3348199999999997
+                        }
+                    }
+                ],
+                "run_loop_busy" : 0.024864200000000003,
+                "uptime_seconds" : 85.002600000000001,
+                "version" : "7.1.0-rc1"
+            },
+            "f483247d4d5f279ef02c549680cbde64" : {
+                "address" : "10.1.19.0:4501",
+                "class_source" : "command_line",
+                "class_type" : "storage",
+                "command_line" : "/usr/bin/fdbserver --class=storage --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.0:4501 --locality_instance_id=storage-2 --locality_machineid=test-cluster-storage-2 --locality_zoneid=test-cluster-storage-2 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.0:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.016351300000000003
+                },
+                "disk" : {
+                    "busy" : 0.0097997999999999991,
+                    "free_bytes" : 84178145280,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 18.599599999999999,
+                        "sectors" : 1456
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-storage-2",
+                "locality" : {
+                    "instance_id" : "storage-2",
+                    "machineid" : "test-cluster-storage-2",
+                    "processid" : "f483247d4d5f279ef02c549680cbde64",
+                    "zoneid" : "test-cluster-storage-2"
+                },
+                "machine_id" : "test-cluster-storage-2",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 196325376
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0.19999600000000001
+                    },
+                    "current_connections" : 9,
+                    "megabits_received" : {
+                        "hz" : 0.072945799999999991
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.094430200000000006
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "role" : "coordinator"
+                    },
+                    {
+                        "commit_batching_window_size" : {
+                            "count" : 39,
+                            "max" : 0.0044400400000000001,
+                            "mean" : 0.0020606499999999998,
+                            "median" : 0.00163269,
+                            "min" : 0.001,
+                            "p25" : 0.001,
+                            "p90" : 0.0038877899999999999,
+                            "p95" : 0.0040663499999999998,
+                            "p99" : 0.0042465699999999999,
+                            "p99.9" : 0.0042465699999999999
+                        },
+                        "commit_latency_statistics" : {
+                            "count" : 31,
+                            "max" : 0.0941882,
+                            "mean" : 0.039759500000000003,
+                            "median" : 0.0079488800000000002,
+                            "min" : 0.0040233099999999996,
+                            "p25" : 0.0054645499999999994,
+                            "p90" : 0.088441099999999995,
+                            "p95" : 0.09051300000000001,
+                            "p99" : 0.090540900000000007,
+                            "p99.9" : 0.090540900000000007
+                        },
+                        "id" : "0eb90e4a0ece85b3",
+                        "role" : "commit_proxy"
+                    },
+                    {
+                        "bytes_queried" : {
+                            "counter" : 0,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "data_lag" : {
+                            "seconds" : 0.19625800000000002,
+                            "versions" : 196258
+                        },
+                        "data_version" : 74805090,
+                        "durability_lag" : {
+                            "seconds" : 5,
+                            "versions" : 5000000
+                        },
+                        "durable_bytes" : {
+                            "counter" : 1106,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "durable_version" : 69805090,
+                        "fetched_versions" : {
+                            "counter" : 74322901,
+                            "hz" : 892381,
+                            "roughness" : 2047820.0000000002
+                        },
+                        "fetches_from_logs" : {
+                            "counter" : 44,
+                            "hz" : 0.59999000000000002,
+                            "roughness" : 0.37684500000000004
+                        },
+                        "finished_queries" : {
+                            "counter" : 0,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "id" : "b5e42e100018bf11",
+                        "input_bytes" : {
+                            "counter" : 1106,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "keys_queried" : {
+                            "counter" : 0,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "kvstore_available_bytes" : 84178112512,
+                        "kvstore_free_bytes" : 84178112512,
+                        "kvstore_inline_keys" : 0,
+                        "kvstore_total_bytes" : 135012552704,
+                        "kvstore_total_nodes" : 0,
+                        "kvstore_total_size" : 0,
+                        "kvstore_used_bytes" : 104861752,
+                        "local_rate" : 100,
+                        "low_priority_queries" : {
+                            "counter" : 0,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "mutation_bytes" : {
+                            "counter" : 52,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "mutations" : {
+                            "counter" : 1,
+                            "hz" : 0,
+                            "roughness" : -1
+                        },
+                        "query_queue_max" : 0,
+                        "read_latency_statistics" : {
+                            "count" : 0,
+                            "max" : 0,
+                            "mean" : 0,
+                            "median" : 0,
+                            "min" : 0,
+                            "p25" : 0,
+                            "p90" : 0,
+                            "p95" : 0,
+                            "p99" : 0,
+                            "p99.9" : 0
+                        },
+                        "role" : "storage",
+                        "storage_metadata" : {
+                            "created_time_datetime" : "Thu Mar 10 17:26:08 2022 +0000",
+                            "created_time_timestamp" : 1646933168295447808
+                        },
+                        "stored_bytes" : 0,
+                        "total_queries" : {
+                            "counter" : 0,
+                            "hz" : 0,
+                            "roughness" : -1
+                        }
+                    }
+                ],
+                "run_loop_busy" : 0.0101502,
+                "uptime_seconds" : 85.002899999999997,
+                "version" : "7.1.0-rc1"
+            },
+            "f6e0f7fd80da429d20329ad95d793ca3" : {
+                "address" : "10.1.19.1:4501",
+                "class_source" : "command_line",
+                "class_type" : "log",
+                "command_line" : "/usr/bin/fdbserver --class=log --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.19.1:4501 --locality_instance_id=log-1 --locality_machineid=test-cluster-log-1 --locality_zoneid=test-cluster-log-1 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.19.1:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.041810800000000002
+                },
+                "disk" : {
+                    "busy" : 0.010199700000000001,
+                    "free_bytes" : 84178165760,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 19.599499999999999,
+                        "sectors" : 1600
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-log-1",
+                "locality" : {
+                    "instance_id" : "log-1",
+                    "machineid" : "test-cluster-log-1",
+                    "processid" : "f6e0f7fd80da429d20329ad95d793ca3",
+                    "zoneid" : "test-cluster-log-1"
+                },
+                "machine_id" : "test-cluster-log-1",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 141787136
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0
+                    },
+                    "current_connections" : 7,
+                    "megabits_received" : {
+                        "hz" : 0.24052400000000002
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.156584
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "id" : "b05dfb13cf568dfd",
+                        "role" : "master"
+                    },
+                    {
+                        "id" : "cfdd8010b58eda01",
+                        "role" : "data_distributor"
+                    },
+                    {
+                        "id" : "cbeb915c6cceb4a9",
+                        "role" : "ratekeeper"
+                    }
+                ],
+                "run_loop_busy" : 0.027578200000000001,
+                "uptime_seconds" : 85.002700000000004,
+                "version" : "7.1.0-rc1"
+            },
+            "f75644abdf1b06c803b5c3c124fdd0a0" : {
+                "address" : "10.1.18.255:4501",
+                "class_source" : "command_line",
+                "class_type" : "cluster_controller",
+                "command_line" : "/usr/bin/fdbserver --class=cluster_controller --cluster_file=/var/fdb/data/fdb.cluster --datadir=/var/fdb/data --knob_disable_posix_kernel_aio=1 --listen_address=10.1.18.255:4501 --locality_instance_id=cluster_controller-1 --locality_machineid=test-cluster-cluster-controller-1 --locality_zoneid=test-cluster-cluster-controller-1 --logdir=/var/log/fdb-trace-logs --loggroup=test-cluster --public_address=10.1.18.255:4501 --seed_cluster_file=/var/dynamic-conf/fdb.cluster",
+                "cpu" : {
+                    "usage_cores" : 0.011798900000000001
+                },
+                "disk" : {
+                    "busy" : 0.010199400000000001,
+                    "free_bytes" : 84178165760,
+                    "reads" : {
+                        "counter" : 6598328,
+                        "hz" : 0,
+                        "sectors" : 0
+                    },
+                    "total_bytes" : 135012552704,
+                    "writes" : {
+                        "counter" : 2167046,
+                        "hz" : 19.598800000000001,
+                        "sectors" : 1600
+                    }
+                },
+                "excluded" : false,
+                "fault_domain" : "test-cluster-cluster-controller-1",
+                "locality" : {
+                    "instance_id" : "cluster_controller-1",
+                    "machineid" : "test-cluster-cluster-controller-1",
+                    "processid" : "f75644abdf1b06c803b5c3c124fdd0a0",
+                    "zoneid" : "test-cluster-cluster-controller-1"
+                },
+                "machine_id" : "test-cluster-cluster-controller-1",
+                "memory" : {
+                    "available_bytes" : 8589934592,
+                    "limit_bytes" : 8589934592,
+                    "unused_allocated_memory" : 0,
+                    "used_bytes" : 142704640
+                },
+                "messages" : [
+                ],
+                "network" : {
+                    "connection_errors" : {
+                        "hz" : 0
+                    },
+                    "connections_closed" : {
+                        "hz" : 0
+                    },
+                    "connections_established" : {
+                        "hz" : 0.199988
+                    },
+                    "current_connections" : 9,
+                    "megabits_received" : {
+                        "hz" : 0.18640100000000001
+                    },
+                    "megabits_sent" : {
+                        "hz" : 0.18823100000000001
+                    },
+                    "tls_policy_failures" : {
+                        "hz" : 0
+                    }
+                },
+                "roles" : [
+                    {
+                        "id" : "1f953018ad2e746f",
+                        "role" : "cluster_controller"
+                    }
+                ],
+                "run_loop_busy" : 0.0075524900000000002,
+                "uptime_seconds" : 85.002899999999997,
+                "version" : "7.1.0-rc1"
+            }
+        },
+        "protocol_version" : "fdb00b071010000",
+        "qos" : {
+            "batch_performance_limited_by" : {
+                "description" : "The database is not being saturated by the workload.",
+                "name" : "workload",
+                "reason_id" : 2
+            },
+            "batch_released_transactions_per_second" : 0.21091300000000002,
+            "batch_transactions_per_second_limit" : 97585900,
+            "limiting_data_lag_storage_server" : {
+                "seconds" : 0,
+                "versions" : 0
+            },
+            "limiting_durability_lag_storage_server" : {
+                "seconds" : 5.0145299999999997,
+                "versions" : 5014530
+            },
+            "limiting_queue_bytes_storage_server" : 1996,
+            "performance_limited_by" : {
+                "description" : "The database is not being saturated by the workload.",
+                "name" : "workload",
+                "reason_id" : 2
+            },
+            "released_transactions_per_second" : 6.0522499999999999,
+            "throttled_tags" : {
+                "auto" : {
+                    "busy_read" : 0,
+                    "busy_write" : 0,
+                    "count" : 0,
+                    "recommended_only" : 0
+                },
+                "manual" : {
+                    "count" : 0
+                }
+            },
+            "transactions_per_second_limit" : 159461000,
+            "worst_data_lag_storage_server" : {
+                "seconds" : 0,
+                "versions" : 0
+            },
+            "worst_durability_lag_storage_server" : {
+                "seconds" : 5.0150199999999998,
+                "versions" : 5015017
+            },
+            "worst_queue_bytes_log_server" : 12144,
+            "worst_queue_bytes_storage_server" : 1996
+        },
+        "recovery_state" : {
+            "active_generations" : 1,
+            "description" : "Recovery complete.",
+            "name" : "fully_recovered",
+            "seconds_since_last_recovered" : 76.8155
+        },
+        "workload" : {
+            "bytes" : {
+                "read" : {
+                    "counter" : 450479,
+                    "hz" : 5819.1099999999997,
+                    "roughness" : 4053.9899999999998
+                },
+                "written" : {
+                    "counter" : 4904,
+                    "hz" : 13.999600000000001,
+                    "roughness" : 69
+                }
+            },
+            "keys" : {
+                "read" : {
+                    "counter" : 2100,
+                    "hz" : 25.7988,
+                    "roughness" : 16.829899999999999
+                }
+            },
+            "operations" : {
+                "location_requests" : {
+                    "counter" : 56,
+                    "hz" : 0.39998900000000004,
+                    "roughness" : 0.97065500000000005
+                },
+                "low_priority_reads" : {
+                    "counter" : 0,
+                    "hz" : 0,
+                    "roughness" : 0
+                },
+                "memory_errors" : {
+                    "counter" : 0,
+                    "hz" : 0,
+                    "roughness" : 0
+                },
+                "read_requests" : {
+                    "counter" : 872,
+                    "hz" : 8.5995899999999992,
+                    "roughness" : 4.2513800000000002
+                },
+                "reads" : {
+                    "counter" : 872,
+                    "hz" : 8.5995899999999992,
+                    "roughness" : 4.2513800000000002
+                },
+                "writes" : {
+                    "counter" : 74,
+                    "hz" : 0.39998900000000004,
+                    "roughness" : 1
+                }
+            },
+            "transactions" : {
+                "committed" : {
+                    "counter" : 32,
+                    "hz" : 0.39998900000000004,
+                    "roughness" : 0.08752349999999999
+                },
+                "conflicted" : {
+                    "counter" : 9,
+                    "hz" : 0,
+                    "roughness" : 0
+                },
+                "rejected_for_queued_too_long" : {
+                    "counter" : 0,
+                    "hz" : 0,
+                    "roughness" : 0
+                },
+                "started" : {
+                    "counter" : 429,
+                    "hz" : 5.99993,
+                    "roughness" : 2.8608099999999999
+                },
+                "started_batch_priority" : {
+                    "counter" : 14,
+                    "hz" : 0.19999800000000001,
+                    "roughness" : 0
+                },
+                "started_default_priority" : {
+                    "counter" : 192,
+                    "hz" : 2.7999700000000001,
+                    "roughness" : 1.2489600000000001
+                },
+                "started_immediate_priority" : {
+                    "counter" : 223,
+                    "hz" : 2.9999700000000002,
+                    "roughness" : 1.4561900000000001
+                }
+            }
+        }
+    }
+}
diff --git a/controllers/admin_client_test.go b/controllers/admin_client_test.go
index 2a969afb..d9ab6ded 100644
--- a/controllers/admin_client_test.go
+++ b/controllers/admin_client_test.go
@@ -71,11 +71,13 @@ var _ = Describe("admin_client_test", func() {
 					StorageEngine:  "ssd-2",
 					UsableRegions:  1,
 					RoleCounts: fdbv1beta2.RoleCounts{
-						Logs:       3,
-						Proxies:    3,
-						Resolvers:  1,
-						LogRouters: -1,
-						RemoteLogs: -1,
+						Logs:          3,
+						Proxies:       3,
+						CommitProxies: 2,
+						GrvProxies:    1,
+						Resolvers:     1,
+						LogRouters:    -1,
+						RemoteLogs:    -1,
 					},
 					VersionFlags: fdbv1beta2.VersionFlags{
 						LogSpill: 2,
diff --git a/controllers/cluster_controller_test.go b/controllers/cluster_controller_test.go
index 33607515..1ec6e813 100644
--- a/controllers/cluster_controller_test.go
+++ b/controllers/cluster_controller_test.go
@@ -226,11 +226,13 @@ var _ = Describe("cluster_controller", func() {
 				Expect(adminClient.DatabaseConfiguration.RedundancyMode).To(Equal(fdbv1beta2.RedundancyModeDouble))
 				Expect(adminClient.DatabaseConfiguration.StorageEngine).To(Equal(fdbv1beta2.StorageEngineSSD2))
 				Expect(adminClient.DatabaseConfiguration.RoleCounts).To(Equal(fdbv1beta2.RoleCounts{
-					Logs:       3,
-					Proxies:    3,
-					Resolvers:  1,
-					RemoteLogs: -1,
-					LogRouters: -1,
+					Logs:          3,
+					Proxies:       3,
+					CommitProxies: 2,
+					GrvProxies:    1,
+					Resolvers:     1,
+					RemoteLogs:    -1,
+					LogRouters:    -1,
 				}))
 			})
 
@@ -1164,7 +1166,7 @@ var _ = Describe("cluster_controller", func() {
 
 					configuration := cluster.DesiredDatabaseConfiguration()
 					configuration.LogVersion = 3
-					err = adminClient.ConfigureDatabase(configuration, false)
+					err = adminClient.ConfigureDatabase(configuration, false, cluster.Spec.Version)
 					Expect(err).NotTo(HaveOccurred())
 
 					generationGap = 1
diff --git a/kubectl-fdb/cmd/configuration_test.go b/kubectl-fdb/cmd/configuration_test.go
index b886ddde..1b4fd1ad 100644
--- a/kubectl-fdb/cmd/configuration_test.go
+++ b/kubectl-fdb/cmd/configuration_test.go
@@ -54,6 +54,7 @@ var _ = Describe("[plugin] configuration command", func() {
 								},
 							},
 						},
+						Version: fdbv1beta2.Versions.Default.String(),
 					},
 				}
 			})
@@ -66,7 +67,7 @@ var _ = Describe("[plugin] configuration command", func() {
 
 				configuration, err := getConfigurationString(kubeClient, "test", "test", false)
 				Expect(err).NotTo(HaveOccurred())
-				Expect(configuration).To(Equal("  usable_regions=0 logs=0 proxies=0 resolvers=0 log_routers=0 remote_logs=0 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"test\\\",\\\"priority\\\":1}]}]"))
+				Expect(configuration).To(Equal("  usable_regions=0 logs=0 resolvers=0 log_routers=0 remote_logs=0 proxies=3 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"test\\\",\\\"priority\\\":1}]}]"))
 			})
 
 			It("should return the same configuration string with failover", func() {
@@ -77,7 +78,7 @@ var _ = Describe("[plugin] configuration command", func() {
 
 				configuration, err := getConfigurationString(kubeClient, "test", "test", true)
 				Expect(err).NotTo(HaveOccurred())
-				Expect(configuration).To(Equal("  usable_regions=0 logs=0 proxies=0 resolvers=0 log_routers=0 remote_logs=0 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"test\\\",\\\"priority\\\":1}]}]"))
+				Expect(configuration).To(Equal("  usable_regions=0 logs=0 resolvers=0 log_routers=0 remote_logs=0 proxies=3 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"test\\\",\\\"priority\\\":1}]}]"))
 			})
 		})
 
@@ -131,6 +132,7 @@ var _ = Describe("[plugin] configuration command", func() {
 								},
 							},
 						},
+						Version: fdbv1beta2.Versions.Default.String(),
 					},
 				}
 
@@ -144,7 +146,7 @@ var _ = Describe("[plugin] configuration command", func() {
 
 				configuration, err := getConfigurationString(kubeClient, "test", "test", false)
 				Expect(err).NotTo(HaveOccurred())
-				Expect(configuration).To(Equal("  usable_regions=0 logs=0 proxies=0 resolvers=0 log_routers=0 remote_logs=0 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"primary\\\",\\\"priority\\\":1},{\\\"id\\\":\\\"primary-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"remote-sat\\\",\\\"satellite\\\":1}]},{\\\"datacenters\\\":[{\\\"id\\\":\\\"remote\\\"},{\\\"id\\\":\\\"remote-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"primary-sat\\\",\\\"satellite\\\":1}]}]"))
+				Expect(configuration).To(Equal("  usable_regions=0 logs=0 resolvers=0 log_routers=0 remote_logs=0 proxies=3 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"primary\\\",\\\"priority\\\":1},{\\\"id\\\":\\\"primary-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"remote-sat\\\",\\\"satellite\\\":1}]},{\\\"datacenters\\\":[{\\\"id\\\":\\\"remote\\\"},{\\\"id\\\":\\\"remote-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"primary-sat\\\",\\\"satellite\\\":1}]}]"))
 			})
 
 			It("should return the configuration string with the modified priority", func() {
@@ -155,7 +157,7 @@ var _ = Describe("[plugin] configuration command", func() {
 
 				configuration, err := getConfigurationString(kubeClient, "test", "test", true)
 				Expect(err).NotTo(HaveOccurred())
-				Expect(configuration).To(Equal("  usable_regions=0 logs=0 proxies=0 resolvers=0 log_routers=0 remote_logs=0 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"primary\\\"},{\\\"id\\\":\\\"primary-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"remote-sat\\\",\\\"satellite\\\":1}]},{\\\"datacenters\\\":[{\\\"id\\\":\\\"remote\\\",\\\"priority\\\":1},{\\\"id\\\":\\\"remote-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"primary-sat\\\",\\\"satellite\\\":1}]}]"))
+				Expect(configuration).To(Equal("  usable_regions=0 logs=0 resolvers=0 log_routers=0 remote_logs=0 proxies=3 regions=[{\\\"datacenters\\\":[{\\\"id\\\":\\\"primary\\\"},{\\\"id\\\":\\\"primary-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"remote-sat\\\",\\\"satellite\\\":1}]},{\\\"datacenters\\\":[{\\\"id\\\":\\\"remote\\\",\\\"priority\\\":1},{\\\"id\\\":\\\"remote-sat\\\",\\\"priority\\\":1,\\\"satellite\\\":1},{\\\"id\\\":\\\"primary-sat\\\",\\\"satellite\\\":1}]}]"))
 			})
 		})
 	})