Repository: mrparkers/terraform-provider-keycloak
Pull request #441 (2020-11-23 14:44:12)

Fix import of service account realm role mapping


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index dd77b4f..6765d10 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -6,13 +6,13 @@ workflows:
           matrix:
             parameters:
               keycloak-version:
-                - '11.0.1'
+                - '11.0.3'
                 - '10.0.2'
                 - '9.0.3'
 
 defaults:
   go_image: &go_image
-    - image: circleci/golang:1.13.5
+    - image: circleci/golang:1.15.5
 
 jobs:
   test:
@@ -22,7 +22,7 @@ jobs:
     docker:
       - <<: *go_image
       - image: jboss/keycloak:<< parameters.keycloak-version >>
-        command: ["-b", "0.0.0.0", "-Dkeycloak.profile.feature.upload_scripts=enabled"]
+        command: ["-b", "0.0.0.0", "-Dkeycloak.profile.feature.upload_scripts=enabled", "-Dkeycloak.profile.feature.admin_fine_grained_authz=enabled", "-Dkeycloak.profile.feature.token_exchange=enabled"]
         environment:
           DB_VENDOR: H2
           KEYCLOAK_LOGLEVEL: DEBUG
@@ -74,4 +74,4 @@ jobs:
       TEST_RESULTS: /tmp/test-results
       CHECKPOINT_DISABLE: "1"
       TF_ACC_TERRAFORM_PATH: "/usr/local/bin/terraform"
-      TF_VERSION: "0.13.0"
+      TF_VERSION: "0.13.5"
diff --git a/README.md b/README.md
index b1ca78d..4f8b4d2 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@ build you can use the `linux_amd64` build as long as `libc6-compat` is installed
 
 ## Development
 
-This project requires Go 1.13 and Terraform 0.13.
+This project requires Go 1.15 and Terraform 0.13.
 This project uses [Go Modules](https://github.com/golang/go/wiki/Modules) for dependency management, which allows this project to exist outside of an existing GOPATH.
 
 After cloning the repository, you can build the project by running `make build`.
diff --git a/docker-compose.yml b/docker-compose.yml
index 7088737..e2103f2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,7 +17,7 @@ services:
     ports:
     - 8389:389
   keycloak:
-    image:  jboss/keycloak:10.0.2
+    image:  jboss/keycloak:11.0.3
     command: -b 0.0.0.0 -Dkeycloak.profile.feature.upload_scripts=enabled -Dkeycloak.profile.feature.admin_fine_grained_authz=enabled -Dkeycloak.profile.feature.token_exchange=enabled
     depends_on:
     - postgres
diff --git a/go.mod b/go.mod
index f706892..2f70de9 100644
--- a/go.mod
+++ b/go.mod
@@ -7,4 +7,4 @@ require (
 	golang.org/x/net v0.0.0-20200707034311-ab3426394381
 )
 
-go 1.13
+go 1.15
diff --git a/keycloak/keycloak_client.go b/keycloak/keycloak_client.go
index d914e72..6a102dc 100644
--- a/keycloak/keycloak_client.go
+++ b/keycloak/keycloak_client.go
@@ -6,6 +6,7 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"fmt"
+	"github.com/hashicorp/go-version"
 	"io"
 	"io/ioutil"
 	"log"
@@ -26,6 +27,7 @@ type KeycloakClient struct {
 	httpClient        *http.Client
 	initialLogin      bool
 	userAgent         string
+	version           *version.Version
 }
 
 type ClientCredentials struct {
@@ -138,7 +140,6 @@ func (keycloakClient *KeycloakClient) login() error {
 
 	var clientCredentials ClientCredentials
 	err = json.Unmarshal(body, &clientCredentials)
-
 	if err != nil {
 		return err
 	}
@@ -147,6 +148,18 @@ func (keycloakClient *KeycloakClient) login() error {
 	keycloakClient.clientCredentials.RefreshToken = clientCredentials.RefreshToken
 	keycloakClient.clientCredentials.TokenType = clientCredentials.TokenType
 
+	info, err := keycloakClient.GetServerInfo()
+	if err != nil {
+		return err
+	}
+
+	v, err := version.NewVersion(info.SystemInfo.ServerVersion)
+	if err != nil {
+		return err
+	}
+
+	keycloakClient.version = v
+
 	return nil
 }
 
diff --git a/keycloak/version.go b/keycloak/version.go
new file mode 100644
index 0000000..2792786
--- /dev/null
+++ b/keycloak/version.go
@@ -0,0 +1,20 @@
+package keycloak
+
+import "github.com/hashicorp/go-version"
+
+type Version string
+
+const (
+	Version_6  Version = "6.0.0"
+	Version_7  Version = "7.0.0"
+	Version_8  Version = "8.0.0"
+	Version_9  Version = "9.0.0"
+	Version_10 Version = "10.0.0"
+	Version_11 Version = "11.0.0"
+)
+
+func (keycloakClient *KeycloakClient) VersionIsGreaterThanOrEqualTo(versionString Version) bool {
+	v, _ := version.NewVersion(string(versionString))
+
+	return keycloakClient.version.GreaterThanOrEqual(v)
+}
diff --git a/provider/resource_keycloak_openid_client.go b/provider/resource_keycloak_openid_client.go
index d62d628..6cfbefd 100644
--- a/provider/resource_keycloak_openid_client.go
+++ b/provider/resource_keycloak_openid_client.go
@@ -1,10 +1,12 @@
 package provider
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"strings"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
 	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
@@ -205,6 +207,9 @@ func resourceKeycloakOpenidClient() *schema.Resource {
 				Optional: true,
 			},
 		},
+		CustomizeDiff: customdiff.ComputedIf("service_account_user_id", func(ctx context.Context, d *schema.ResourceDiff, meta interface{}) bool {
+			return d.HasChange("service_accounts_enabled")
+		}),
 	}
 }
 
diff --git a/provider/resource_keycloak_openid_client_service_account_realm_role.go b/provider/resource_keycloak_openid_client_service_account_realm_role.go
index e20204c..7f8a16e 100644
--- a/provider/resource_keycloak_openid_client_service_account_realm_role.go
+++ b/provider/resource_keycloak_openid_client_service_account_realm_role.go
@@ -112,14 +112,27 @@ func resourceKeycloakOpenidClientServiceAccountRealmRoleDelete(data *schema.Reso
 	return nil
 }
 
-func resourceKeycloakOpenidClientServiceAccountRealmRoleImport(d *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) {
+func resourceKeycloakOpenidClientServiceAccountRealmRoleImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
 	parts := strings.Split(d.Id(), "/")
-	if len(parts) != 2 {
+	if len(parts) != 3 {
 		return nil, fmt.Errorf("Invalid import. Supported import formats: {{realmId}}/{{serviceAccountUserId}}/{{roleId}}")
 	}
-	d.Set("realm_id", parts[0])
-	d.Set("service_account_user_id", parts[1])
-	d.SetId(fmt.Sprintf("%s/%s", parts[1], parts[2]))
+
+	realmId := parts[0]
+	serviceAccountUserId := parts[1]
+	roleId := parts[2]
+
+	role, err := keycloakClient.GetRole(realmId, roleId)
+	if err != nil {
+		return nil, err
+	}
+
+	d.Set("realm_id", realmId)
+	d.Set("service_account_user_id", serviceAccountUserId)
+	d.Set("role", role.Name)
+	d.SetId(fmt.Sprintf("%s/%s", serviceAccountUserId, roleId))
 
 	return []*schema.ResourceData{d}, nil
 }


Test patch:
diff --git a/provider/resource_keycloak_openid_client_default_scopes_test.go b/provider/resource_keycloak_openid_client_default_scopes_test.go
index 3a25f15..38ea201 100644
--- a/provider/resource_keycloak_openid_client_default_scopes_test.go
+++ b/provider/resource_keycloak_openid_client_default_scopes_test.go
@@ -293,7 +293,7 @@ func TestAccKeycloakOpenidClientDefaultScopes_validateDuplicateScopeAssignment(t
 	client := "terraform-client-" + acctest.RandString(10)
 	clientScope := "terraform-client-scope-" + acctest.RandString(10)
 
-	optionalClientScopes := append(getPreAssignedOptionalClientScopes(t), clientScope)
+	optionalClientScopes := append(getPreAssignedOptionalClientScopes(), clientScope)
 
 	resource.Test(t, resource.TestCase{
 		ProviderFactories: testAccProviderFactories,
diff --git a/provider/resource_keycloak_openid_client_optional_scopes_test.go b/provider/resource_keycloak_openid_client_optional_scopes_test.go
index 12d8851..1451d36 100644
--- a/provider/resource_keycloak_openid_client_optional_scopes_test.go
+++ b/provider/resource_keycloak_openid_client_optional_scopes_test.go
@@ -12,12 +12,8 @@ import (
 )
 
 // All openid clients in Keycloak will automatically have these scopes listed as "optional client scopes".
-func getPreAssignedOptionalClientScopes(t *testing.T) []string {
-	keycloakVersionIsGreaterThanOrEqualTo6, err := keycloakVersionIsGreaterThanOrEqualTo(keycloakClient, getKeycloakVersion600())
-	if err != nil {
-		t.Fatal(err)
-	}
-	if keycloakVersionIsGreaterThanOrEqualTo6 {
+func getPreAssignedOptionalClientScopes() []string {
+	if keycloakClient.VersionIsGreaterThanOrEqualTo(keycloak.Version_6) {
 		return []string{"address", "phone", "offline_access", "microprofile-jwt"}
 	} else {
 		return []string{"address", "phone", "offline_access"}
@@ -29,7 +25,7 @@ func TestAccKeycloakOpenidClientOptionalScopes_basic(t *testing.T) {
 	client := "terraform-client-" + acctest.RandString(10)
 	clientScope := "terraform-client-scope-" + acctest.RandString(10)
 
-	clientScopes := append(getPreAssignedOptionalClientScopes(t), clientScope)
+	clientScopes := append(getPreAssignedOptionalClientScopes(), clientScope)
 
 	resource.Test(t, resource.TestCase{
 		ProviderFactories: testAccProviderFactories,
@@ -55,7 +51,7 @@ func TestAccKeycloakOpenidClientOptionalScopes_updateClientForceNew(t *testing.T
 	clientTwo := "terraform-client-" + acctest.RandString(10)
 	clientScope := "terraform-client-scope-" + acctest.RandString(10)
 
-	clientScopes := append(getPreAssignedOptionalClientScopes(t), clientScope)
+	clientScopes := append(getPreAssignedOptionalClientScopes(), clientScope)
 
 	resource.Test(t, resource.TestCase{
 		ProviderFactories: testAccProviderFactories,
@@ -78,7 +74,7 @@ func TestAccKeycloakOpenidClientOptionalScopes_updateInPlace(t *testing.T) {
 	client := "terraform-client-" + acctest.RandString(10)
 	clientScope := "terraform-client-scope-" + acctest.RandString(10)
 
-	allClientScopes := append(getPreAssignedOptionalClientScopes(t), clientScope)
+	allClientScopes := append(getPreAssignedOptionalClientScopes(), clientScope)
 
 	clientScopeToRemove := allClientScopes[acctest.RandIntRange(0, 2)]
 	var subsetOfClientScopes []string
@@ -149,7 +145,7 @@ func TestAccKeycloakOpenidClientOptionalScopes_validateClientAccessType(t *testi
 func TestAccKeycloakOpenidClientOptionalScopes_authoritativeAdd(t *testing.T) {
 	realm := "terraform-realm-" + acctest.RandString(10)
 	client := "terraform-client-" + acctest.RandString(10)
-	clientScopes := append(getPreAssignedOptionalClientScopes(t),
+	clientScopes := append(getPreAssignedOptionalClientScopes(),
 		"terraform-client-scope-"+acctest.RandString(10),
 		"terraform-client-scope-"+acctest.RandString(10),
 		"terraform-client-scope-"+acctest.RandString(10),
@@ -195,7 +191,7 @@ func TestAccKeycloakOpenidClientOptionalScopes_authoritativeRemove(t *testing.T)
 		"terraform-client-scope-" + acctest.RandString(10),
 		"terraform-client-scope-" + acctest.RandString(10),
 	}
-	allClientScopes := append(getPreAssignedOptionalClientScopes(t), randomClientScopes...)
+	allClientScopes := append(getPreAssignedOptionalClientScopes(), randomClientScopes...)
 
 	clientToManuallyAttach := randomClientScopes[acctest.RandIntRange(0, len(randomClientScopes)-1)]
 	var attachedClientScopes []string
@@ -243,7 +239,7 @@ func TestAccKeycloakOpenidClientOptionalScopes_noImportNeeded(t *testing.T) {
 	client := "terraform-client-" + acctest.RandString(10)
 	clientScope := "terraform-client-scope-" + acctest.RandString(10)
 
-	clientScopes := append(getPreAssignedOptionalClientScopes(t), clientScope)
+	clientScopes := append(getPreAssignedOptionalClientScopes(), clientScope)
 
 	resource.Test(t, resource.TestCase{
 		ProviderFactories: testAccProviderFactories,
@@ -291,7 +287,7 @@ func TestAccKeycloakOpenidClientOptionalScopes_profileAndEmailOptionalScopes(t *
 		Steps: []resource.TestStep{
 			{
 				Config:             testKeycloakOpenidClientOptionalScopes_listOfScopes(realm, client, clientScope, []string{clientScope}),
-				Check:              testAccCheckKeycloakOpenidClientHasOptionalScopes("keycloak_openid_client.client", append(getPreAssignedOptionalClientScopes(t), clientScope)),
+				Check:              testAccCheckKeycloakOpenidClientHasOptionalScopes("keycloak_openid_client.client", append(getPreAssignedOptionalClientScopes(), clientScope)),
 				ExpectNonEmptyPlan: true,
 			},
 		},
@@ -409,8 +405,7 @@ func testAccCheckKeycloakOpenidClientOptionalScopeIsNotAttached(resourceName, cl
 }
 
 func testKeycloakOpenidClientOptionalScopes_basic(realm, client, clientScope string) string {
-	keycloakVersionIsHigherOrEqualTo6, _ := keycloakVersionIsGreaterThanOrEqualTo(keycloakClient, getKeycloakVersion600())
-	if keycloakVersionIsHigherOrEqualTo6 {
+	if keycloakClient.VersionIsGreaterThanOrEqualTo(keycloak.Version_6) {
 		return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
 	realm = "%s"
@@ -525,8 +520,7 @@ resource "keycloak_openid_client_optional_scopes" "optional_scopes" {
 }
 
 func testKeycloakOpenidClientOptionalScopes_validationNoClient(realm, client, clientScope string) string {
-	keycloakVersionIsHigherOrEqualTo6, _ := keycloakVersionIsGreaterThanOrEqualTo(keycloakClient, getKeycloakVersion600())
-	if keycloakVersionIsHigherOrEqualTo6 {
+	if keycloakClient.VersionIsGreaterThanOrEqualTo(keycloak.Version_6) {
 		return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
 	realm = "%s"
@@ -579,9 +573,7 @@ resource "keycloak_openid_client_optional_scopes" "optional_scopes" {
 }
 
 func testKeycloakOpenidClientOptionalScopes_validationBearerOnlyClient(realm, client, clientScope string) string {
-
-	keycloakVersionIsHigherOrEqualTo6, _ := keycloakVersionIsGreaterThanOrEqualTo(keycloakClient, getKeycloakVersion600())
-	if keycloakVersionIsHigherOrEqualTo6 {
+	if keycloakClient.VersionIsGreaterThanOrEqualTo(keycloak.Version_6) {
 		return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
 	realm = "%s"
@@ -689,8 +681,7 @@ resource "keycloak_openid_client_optional_scopes" "optional_scopes" {
 }
 
 func testKeycloakOpenidClientOptionalScopes_duplicateScopeAssignment(realm, client, clientScope string) string {
-	keycloakVersionIsHigherOrEqualTo6, _ := keycloakVersionIsGreaterThanOrEqualTo(keycloakClient, getKeycloakVersion600())
-	if keycloakVersionIsHigherOrEqualTo6 {
+	if keycloakClient.VersionIsGreaterThanOrEqualTo(keycloak.Version_6) {
 		return fmt.Sprintf(`
 %s
 
diff --git a/provider/resource_keycloak_openid_client_service_account_realm_role_test.go b/provider/resource_keycloak_openid_client_service_account_realm_role_test.go
index 9ed8c53..34e4a4d 100644
--- a/provider/resource_keycloak_openid_client_service_account_realm_role_test.go
+++ b/provider/resource_keycloak_openid_client_service_account_realm_role_test.go
@@ -13,6 +13,7 @@ import (
 func TestAccKeycloakOpenidClientServiceAccountRealmRole_basic(t *testing.T) {
 	realmName := "terraform-" + acctest.RandString(10)
 	clientId := "terraform-" + acctest.RandString(10)
+	resourceName := "keycloak_openid_client_service_account_realm_role.test"
 
 	resource.Test(t, resource.TestCase{
 		ProviderFactories: testAccProviderFactories,
@@ -21,7 +22,13 @@ func TestAccKeycloakOpenidClientServiceAccountRealmRole_basic(t *testing.T) {
 		Steps: []resource.TestStep{
 			{
 				Config: testKeycloakOpenidClientServiceAccountRealmRole_basic(realmName, clientId),
-				Check:  testAccCheckKeycloakOpenidClientServiceAccountRealmRoleExists("keycloak_openid_client_service_account_realm_role.test"),
+				Check:  testAccCheckKeycloakOpenidClientServiceAccountRealmRoleExists(resourceName),
+			},
+			{
+				ResourceName:      resourceName,
+				ImportState:       true,
+				ImportStateVerify: true,
+				ImportStateIdFunc: getKeycloakOpenidClientServiceAccountRealmRoleImportId(resourceName),
 			},
 		},
 	})
@@ -155,6 +162,17 @@ func getKeycloakOpenidClientServiceAccountRealmRoleFromState(s *terraform.State,
 	return serviceAccountRole, nil
 }
 
+func getKeycloakOpenidClientServiceAccountRealmRoleImportId(resourceName string) resource.ImportStateIdFunc {
+	return func(s *terraform.State) (string, error) {
+		serviceAccountRole, err := getKeycloakOpenidClientServiceAccountRealmRoleFromState(s, resourceName)
+		if err != nil {
+			return "", err
+		}
+
+		return fmt.Sprintf("%s/%s/%s", serviceAccountRole.RealmId, serviceAccountRole.ServiceAccountUserId, serviceAccountRole.Id), nil
+	}
+}
+
 func testKeycloakOpenidClientServiceAccountRealmRole_basic(realm, clientId string) string {
 	return fmt.Sprintf(`
 resource keycloak_realm test {
diff --git a/provider/resource_keycloak_openid_client_service_account_role_test.go b/provider/resource_keycloak_openid_client_service_account_role_test.go
index 1f3a5c5..77e7e4a 100644
--- a/provider/resource_keycloak_openid_client_service_account_role_test.go
+++ b/provider/resource_keycloak_openid_client_service_account_role_test.go
@@ -93,6 +93,28 @@ func TestAccKeycloakOpenidClientServiceAccountRole_basicUpdateRealm(t *testing.T
 	})
 }
 
+func TestAccKeycloakOpenidClientServiceAccountRole_enableAfterCreate(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	bearerClientId := "terraform-" + acctest.RandString(10)
+	consumerClientId := "terraform-" + acctest.RandString(10)
+	resourceName := "keycloak_openid_client_service_account_role.consumer_service_account_role"
+
+	resource.Test(t, resource.TestCase{
+		ProviderFactories: testAccProviderFactories,
+		PreCheck:          func() { testAccPreCheck(t) },
+		CheckDestroy:      testAccCheckKeycloakOpenidClientServiceAccountRoleDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenidClientServiceAccountRole_enableAfterCreate_before(realmName, bearerClientId, consumerClientId),
+			},
+			{
+				Config: testKeycloakOpenidClientServiceAccountRole_enableAfterCreate_after(realmName, bearerClientId, consumerClientId),
+				Check:  testAccCheckKeycloakOpenidClientServiceAccountRoleExists(resourceName),
+			},
+		},
+	})
+}
+
 func testAccCheckKeycloakOpenidClientServiceAccountRoleExists(resourceName string) resource.TestCheckFunc {
 	return func(s *terraform.State) error {
 		_, err := getKeycloakOpenidClientServiceAccountRoleFromState(s, resourceName)
@@ -184,27 +206,90 @@ func getKeycloakOpenidClientServiceAccountRoleImportId(resourceName string) reso
 
 func testKeycloakOpenidClientServiceAccountRole_basic(realm, clientId string) string {
 	return fmt.Sprintf(`
-resource keycloak_realm test {
+resource "keycloak_realm" "test" {
 	realm = "%s"
 }
 
-resource keycloak_openid_client test {
+resource "keycloak_openid_client" "test" {
 	client_id                = "%s"
-	realm_id                 = "${keycloak_realm.test.id}"
+	realm_id                 = keycloak_realm.test.id
 	access_type              = "CONFIDENTIAL"
 	service_accounts_enabled = true
 }
 
-data keycloak_openid_client broker {
-  realm_id  = "${keycloak_realm.test.id}"
+data "keycloak_openid_client" "broker" {
+  realm_id  = keycloak_realm.test.id
   client_id = "broker"
 }
 
-resource keycloak_openid_client_service_account_role test {
-	service_account_user_id = "${keycloak_openid_client.test.service_account_user_id}"
-	realm_id 					= "${keycloak_realm.test.id}"
-	client_id 					= "${data.keycloak_openid_client.broker.id}"
-	role 							= "read-token"
+resource "keycloak_openid_client_service_account_role" "test" {
+	realm_id                = keycloak_realm.test.id
+	client_id               = data.keycloak_openid_client.broker.id
+	service_account_user_id = keycloak_openid_client.test.service_account_user_id
+	role                    = "read-token"
 }
 	`, realm, clientId)
 }
+
+func testKeycloakOpenidClientServiceAccountRole_enableAfterCreate_before(realm, bearerClientId, consumerClientId string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "test" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "bearer" {
+	client_id   = "%s"
+	realm_id    = keycloak_realm.test.id
+	access_type = "BEARER-ONLY"
+}
+
+resource "keycloak_role" "bearer_role" {
+	realm_id  = keycloak_realm.test.id
+	client_id = keycloak_openid_client.bearer.id
+	name      = "bearer-role"
+}
+
+resource "keycloak_openid_client" "consumer" {
+  realm_id  = keycloak_realm.test.id
+  client_id = "%s"
+
+  access_type              = "CONFIDENTIAL"
+  service_accounts_enabled = false
+}
+	`, realm, bearerClientId, consumerClientId)
+}
+
+func testKeycloakOpenidClientServiceAccountRole_enableAfterCreate_after(realm, bearerClientId, consumerClientId string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "test" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "bearer" {
+	client_id   = "%s"
+	realm_id    = keycloak_realm.test.id
+	access_type = "BEARER-ONLY"
+}
+
+resource "keycloak_role" "bearer_role" {
+	realm_id  = keycloak_realm.test.id
+	client_id = keycloak_openid_client.bearer.id
+	name      = "bearer-role"
+}
+
+resource "keycloak_openid_client" "consumer" {
+  realm_id  = keycloak_realm.test.id
+  client_id = "%s"
+
+  access_type              = "CONFIDENTIAL"
+  service_accounts_enabled = true
+}
+
+resource "keycloak_openid_client_service_account_role" "consumer_service_account_role" {
+  realm_id                = keycloak_realm.test.id
+  service_account_user_id = keycloak_openid_client.consumer.service_account_user_id
+  client_id               = keycloak_openid_client.bearer.id
+  role                    = keycloak_role.bearer_role.name
+}
+	`, realm, bearerClientId, consumerClientId)
+}
diff --git a/provider/resource_keycloak_realm_events_test.go b/provider/resource_keycloak_realm_events_test.go
index 2f5f65f..fd26836 100644
--- a/provider/resource_keycloak_realm_events_test.go
+++ b/provider/resource_keycloak_realm_events_test.go
@@ -164,13 +164,9 @@ func TestAccKeycloakRealmEvents_unsetEnabledEventTypes(t *testing.T) {
 						if err != nil {
 							return err
 						}
-						keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
-						keycloakVersionIsGreaterThanOrEqualTo7, err := keycloakVersionIsGreaterThanOrEqualTo(keycloakClient, getKeycloakVersion700())
-						if err != nil {
-							return err
-						}
 
-						if keycloakVersionIsGreaterThanOrEqualTo7 { //keycloak versions < 7.0.0 have 63 events, versions >=7.0.0 have 67 events
+						keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+						if keycloakClient.VersionIsGreaterThanOrEqualTo(keycloak.Version_7) { //keycloak versions < 7.0.0 have 63 events, versions >=7.0.0 have 67 events
 							if len(realmEventsConfig.EnabledEventTypes) != 67 {
 								return fmt.Errorf("exptected to enabled_event_types to contain all(67) event types, but it contains %d", len(realmEventsConfig.EnabledEventTypes))
 							}
diff --git a/provider/test_utils.go b/provider/test_utils.go
index d54480b..90924b2 100644
--- a/provider/test_utils.go
+++ b/provider/test_utils.go
@@ -2,11 +2,8 @@ package provider
 
 import (
 	"fmt"
-	"github.com/hashicorp/go-version"
-	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
 	"math/rand"
 	"os"
-	"regexp"
 	"strings"
 	"testing"
 	"time"
@@ -78,48 +75,3 @@ func TestCheckResourceAttrNot(name, key, value string) resource.TestCheckFunc {
 		return nil
 	}
 }
-
-var keycloakServerInfoVersion *version.Version
-
-func keycloakVersionIsGreaterThanOrEqualTo(keycloakClient *keycloak.KeycloakClient, keycloakMajorVersion *version.Version) (bool, error) {
-	if keycloakServerInfoVersion == nil {
-		serverInfo, err := keycloakClient.GetServerInfo()
-		if err != nil {
-			return false, fmt.Errorf("/serverInfo endpoint retuned an error, server Keycloak version could not be determined: %s", err)
-		}
-
-		regex := regexp.MustCompile(`^(\d+\.\d+\.\d+)`)
-		semver := regex.FindStringSubmatch(serverInfo.SystemInfo.ServerVersion)[0]
-
-		keycloakServerInfoVersion, err = version.NewVersion(semver)
-		if err != nil {
-			return false, fmt.Errorf("/serverInfo endpoint retuned an unreadable version, server Keycloak version could not be determined: %s", err)
-		}
-	}
-	return keycloakServerInfoVersion.GreaterThanOrEqual(keycloakMajorVersion), nil
-}
-
-func getKeycloakVersion600() *version.Version {
-	v, _ := version.NewVersion("6.0.0")
-	return v
-}
-
-func getKeycloakVersion700() *version.Version {
-	v, _ := version.NewVersion("7.0.0")
-	return v
-}
-
-func getKeycloakVersion800() *version.Version {
-	v, _ := version.NewVersion("8.0.0")
-	return v
-}
-
-func getKeycloakVersion900() *version.Version {
-	v, _ := version.NewVersion("9.0.0")
-	return v
-}
-
-func getKeycloakVersion1000() *version.Version {
-	v, _ := version.NewVersion("10.0.0")
-	return v
-}