Repository: mrparkers/terraform-provider-keycloak
Pull request #444 (2020-11-30 16:36:48)

add ability to check current keycloak version via client


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index dd77b4f..94d6809 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -6,7 +6,7 @@ workflows:
           matrix:
             parameters:
               keycloak-version:
-                - '11.0.1'
+                - '11.0.3'
                 - '10.0.2'
                 - '9.0.3'
 
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/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)
+}


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_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
-}