func()

in providers/keycloak/generator.go [349:633]


func (g *RealmGenerator) PostConvertHook() error {
	mapRealmIDs := map[string]string{}
	mapUserFederationIDs := map[string]string{}
	mapGroupIDs := map[string]string{}
	mapClientIDs := map[string]string{}
	mapClientNames := map[string]string{}
	mapClientClientIDs := map[string]string{}
	mapClientClientNames := map[string]string{}
	mapServiceAccountUserIDs := map[string]string{}
	mapRoleIDs := map[string]string{}
	mapClientRoleNames := map[string]string{}
	mapClientRoleShortNames := map[string]string{}
	mapScopeNames := map[string]string{}
	mapUserNames := map[string]string{}
	mapGroupNames := map[string]string{}
	mapAuthenticationFlowAliases := map[string]string{}
	mapAuthenticationExecutionIDs := map[string]string{}

	// Set slices to be able to map IDs with Terraform variables
	for _, r := range g.Resources {
		if r.InstanceInfo.Type != "keycloak_realm" &&
			r.InstanceInfo.Type != "keycloak_ldap_user_federation" &&
			r.InstanceInfo.Type != "keycloak_group" &&
			r.InstanceInfo.Type != "keycloak_openid_client" &&
			r.InstanceInfo.Type != "keycloak_role" &&
			r.InstanceInfo.Type != "keycloak_openid_client_scope" &&
			r.InstanceInfo.Type != "keycloak_user" &&
			r.InstanceInfo.Type != "keycloak_authentication_flow" &&
			r.InstanceInfo.Type != "keycloak_authentication_subflow" &&
			r.InstanceInfo.Type != "keycloak_authentication_execution" {
			continue
		}
		if r.InstanceInfo.Type == "keycloak_realm" {
			mapRealmIDs[r.InstanceState.ID] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".id}"
		}
		if r.InstanceInfo.Type == "keycloak_ldap_user_federation" {
			mapUserFederationIDs[r.Item["realm_id"].(string)+"_"+r.InstanceState.ID] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".id}"
		}
		if r.InstanceInfo.Type == "keycloak_group" {
			mapGroupIDs[r.Item["realm_id"].(string)+"_"+r.InstanceState.ID] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".id}"
			mapGroupNames[r.Item["realm_id"].(string)+"_"+r.Item["name"].(string)] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".name}"
		}
		if r.InstanceInfo.Type == "keycloak_openid_client" {
			mapClientIDs[r.Item["realm_id"].(string)+"_"+r.InstanceState.ID] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".id}"
			mapClientNames[r.Item["realm_id"].(string)+"_"+r.InstanceState.ID] = r.Item["client_id"].(string)
			mapClientClientNames[r.Item["realm_id"].(string)+"_"+r.InstanceState.ID] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".client_id}"
			mapClientClientIDs[r.Item["realm_id"].(string)+"_"+r.InstanceState.Attributes["client_id"]] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".client_id}"
			if _, exist := r.InstanceState.Attributes["service_account_user_id"]; exist {
				mapServiceAccountUserIDs[r.Item["realm_id"].(string)+"_"+r.InstanceState.Attributes["service_account_user_id"]] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".service_account_user_id}"
			}
		}
		if r.InstanceInfo.Type == "keycloak_openid_client_scope" {
			mapScopeNames[r.Item["realm_id"].(string)+"_"+r.Item["name"].(string)] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".name}"
		}
		if r.InstanceInfo.Type == "keycloak_user" {
			mapUserNames[r.Item["realm_id"].(string)+"_"+r.Item["username"].(string)] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".username}"
		}
		if r.InstanceInfo.Type == "keycloak_authentication_flow" || r.InstanceInfo.Type == "keycloak_authentication_subflow" {
			mapAuthenticationFlowAliases[r.Item["realm_id"].(string)+"_"+r.Item["alias"].(string)] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".alias}"
		}
		if r.InstanceInfo.Type == "keycloak_authentication_execution" {
			mapAuthenticationExecutionIDs[r.Item["realm_id"].(string)+"_"+r.InstanceState.ID] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".id}"
		}
	}

	// Set slices to be able to map IDs with Terraform variables
	// Separate loop for roles to avoid fetching with a key that is not present in the map
	for _, r := range g.Resources {
		if r.InstanceInfo.Type == "keycloak_role" {
			mapRoleIDs[r.Item["realm_id"].(string)+"_"+r.InstanceState.ID] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".id}"
			if _, exist := r.Item["client_id"]; exist {
				mapClientRoleNames[r.Item["realm_id"].(string)+"_"+mapClientNames[r.Item["realm_id"].(string)+"_"+r.Item["client_id"].(string)]+"."+r.Item["name"].(string)] = mapClientClientNames[r.Item["realm_id"].(string)+"_"+r.Item["client_id"].(string)] + ".${" + r.InstanceInfo.Type + "." + r.ResourceName + ".name}"
				mapClientRoleShortNames[r.Item["realm_id"].(string)+"_"+mapClientNames[r.Item["realm_id"].(string)+"_"+r.Item["client_id"].(string)]+"."+r.Item["name"].(string)] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".name}"
			} else {
				mapClientRoleNames[r.Item["realm_id"].(string)+"_"+r.Item["name"].(string)] = "${" + r.InstanceInfo.Type + "." + r.ResourceName + ".name}"
			}
		}
	}

	// For each resource, modify import if needed...
	for i, r := range g.Resources {
		// Escape keycloak text inputs not to get unpredictable results or errors when Terraform will try to interpret variables ($ vs $$)
		// TODO: ensure that we escape all existing fields
		if strings.Contains(r.InstanceState.Attributes["consent_screen_text"], "$") {
			g.Resources[i].Item["consent_screen_text"] = strings.ReplaceAll(r.InstanceState.Attributes["consent_screen_text"], "$", "$$")
		}
		if strings.Contains(r.InstanceState.Attributes["name"], "$") {
			g.Resources[i].Item["name"] = strings.ReplaceAll(r.InstanceState.Attributes["name"], "$", "$$")
		}
		if strings.Contains(r.InstanceState.Attributes["description"], "$") {
			g.Resources[i].Item["description"] = strings.ReplaceAll(r.InstanceState.Attributes["description"], "$", "$$")
		}
		if strings.Contains(r.InstanceState.Attributes["root_url"], "$") {
			g.Resources[i].Item["root_url"] = strings.ReplaceAll(r.InstanceState.Attributes["root_url"], "$", "$$")
		}

		// Sort supported_locales to get reproducible results for keycloak_realm resources
		if r.InstanceInfo.Type == "keycloak_realm" {
			if _, exist := r.Item["internationalization"]; exist {
				for _, v := range r.Item["internationalization"].([]interface{}) {
					sortedSupportedLocales := make([]string, len(v.(map[string]interface{})["supported_locales"].([]interface{})))
					for k, vv := range v.(map[string]interface{})["supported_locales"].([]interface{}) {
						sortedSupportedLocales[k] = vv.(string)
					}
					sort.Strings(sortedSupportedLocales)
					v.(map[string]interface{})["supported_locales"] = sortedSupportedLocales
				}
			}
		}

		// Sort group_ids to get reproducible results for keycloak_default_groups resources
		// Set an empty string slice if the attribute doesn't exist as it is mandatory
		if r.InstanceInfo.Type == "keycloak_default_groups" {
			if _, exist := r.Item["group_ids"]; exist {
				renamedGroupIDs := make([]string, len(r.Item["group_ids"].([]interface{})))
				for k, v := range r.Item["group_ids"].([]interface{}) {
					renamedGroupIDs[k] = mapGroupIDs[r.Item["realm_id"].(string)+"_"+v.(string)]
				}
				sort.Strings(renamedGroupIDs)
				g.Resources[i].Item["group_ids"] = renamedGroupIDs
			} else {
				g.Resources[i].Item["group_ids"] = []string{}
			}
		}

		// Sort valid_redirect_uris and web_origins to get reproducible results for keycloak_openid_client resources
		if r.InstanceInfo.Type == "keycloak_openid_client" {
			if _, exist := r.Item["valid_redirect_uris"]; exist {
				sortedValidRedirectUris := make([]string, len(r.Item["valid_redirect_uris"].([]interface{})))
				for k, v := range r.Item["valid_redirect_uris"].([]interface{}) {
					sortedValidRedirectUris[k] = v.(string)
				}
				sort.Strings(sortedValidRedirectUris)
				g.Resources[i].Item["valid_redirect_uris"] = sortedValidRedirectUris
			}

			if _, exist := r.Item["web_origins"]; exist {
				sortedWebOrigins := make([]string, len(r.Item["web_origins"].([]interface{})))
				for k, v := range r.Item["web_origins"].([]interface{}) {
					sortedWebOrigins[k] = v.(string)
				}
				sort.Strings(sortedWebOrigins)
				g.Resources[i].Item["web_origins"] = sortedWebOrigins
			}
		}

		// Sort composite_roles to get reproducible results for keycloak_role resources
		if _, exist := r.Item["composite_roles"]; exist && r.InstanceInfo.Type == "keycloak_role" {
			renamedCompositeRoles := make([]string, len(r.Item["composite_roles"].([]interface{})))
			for k, v := range r.Item["composite_roles"].([]interface{}) {
				renamedCompositeRoles[k] = mapRoleIDs[r.Item["realm_id"].(string)+"_"+v.(string)]
			}
			sort.Strings(renamedCompositeRoles)
			g.Resources[i].Item["composite_roles"] = renamedCompositeRoles
		}

		// Sort default_scopes to get reproducible results for keycloak_openid_client_default_scopes resources
		if _, exist := r.Item["default_scopes"]; exist && r.InstanceInfo.Type == "keycloak_openid_client_default_scopes" {
			renamedScopes := make([]string, len(r.Item["default_scopes"].([]interface{})))
			for k, v := range r.Item["default_scopes"].([]interface{}) {
				renamedScopes[k] = mapScopeNames[r.Item["realm_id"].(string)+"_"+v.(string)]
			}
			sort.Strings(renamedScopes)
			g.Resources[i].Item["default_scopes"] = renamedScopes
		}

		// Sort optional_scopes to get reproducible results for keycloak_openid_client_optional_scopes resources
		if _, exist := r.Item["optional_scopes"]; exist && r.InstanceInfo.Type == "keycloak_openid_client_optional_scopes" {
			renamedScopes := make([]string, len(r.Item["optional_scopes"].([]interface{})))
			for k, v := range r.Item["optional_scopes"].([]interface{}) {
				renamedScopes[k] = mapScopeNames[r.Item["realm_id"].(string)+"_"+v.(string)]
			}
			sort.Strings(renamedScopes)
			g.Resources[i].Item["optional_scopes"] = renamedScopes
		}

		// Sort role_ids to get reproducible results for keycloak_group_roles resources
		if r.InstanceInfo.Type == "keycloak_group_roles" {
			if roleIDs, ok := r.Item["role_ids"].([]interface{}); ok {
				sortedRoles := make([]string, len(roleIDs))
				for k, v := range roleIDs {
					sortedRoles[k] = mapRoleIDs[r.Item["realm_id"].(string)+"_"+v.(string)]
				}
				sort.Strings(sortedRoles)
				g.Resources[i].Item["role_ids"] = sortedRoles
			} else {
				g.Resources[i].Item["role_ids"] = []string{}
			}
		}

		// Sort members to get reproducible results for keycloak_group_memberships resources
		// Map members to keycloak_user.foo.username Terraform variables
		if r.InstanceInfo.Type == "keycloak_group_memberships" {
			sortedMembers := make([]string, len(r.Item["members"].([]interface{})))
			for k, v := range r.Item["members"].([]interface{}) {
				if mapUserNames[r.Item["realm_id"].(string)+"_"+v.(string)] != "" {
					sortedMembers[k] = mapUserNames[r.Item["realm_id"].(string)+"_"+v.(string)]
				} else {
					sortedMembers[k] = v.(string)
				}
			}
			sort.Strings(sortedMembers)
			g.Resources[i].Item["members"] = sortedMembers
		}

		// Map ldap_user_federation_id attributes to keycloak_ldap_user_federation.foo.id Terraform variables for ldap mappers resources
		if r.InstanceInfo.Type == "keycloak_ldap_full_name_mapper" ||
			r.InstanceInfo.Type == "keycloak_ldap_group_mapper" ||
			r.InstanceInfo.Type == "keycloak_ldap_role_mapper" ||
			r.InstanceInfo.Type == "keycloak_ldap_hardcoded_group_mapper" ||
			r.InstanceInfo.Type == "keycloak_ldap_hardcoded_role_mapper" ||
			r.InstanceInfo.Type == "keycloak_ldap_msad_lds_user_account_control_mapper" ||
			r.InstanceInfo.Type == "keycloak_ldap_msad_user_account_control_mapper" ||
			r.InstanceInfo.Type == "keycloak_ldap_user_attribute_mapper" {
			g.Resources[i].Item["ldap_user_federation_id"] = mapUserFederationIDs[r.Item["realm_id"].(string)+"_"+g.Resources[i].Item["ldap_user_federation_id"].(string)]
		}

		// Map group to keycloak_group.foo.name Terraform variables for ldap hardcoded group mapper resources
		if r.InstanceInfo.Type == "keycloak_ldap_hardcoded_group_mapper" {
			g.Resources[i].Item["group"] = mapGroupNames[r.Item["realm_id"].(string)+"_"+r.Item["group"].(string)]
		}

		// Map role to Terraform variables for ldap hardcoded role mapper resources
		if r.InstanceInfo.Type == "keycloak_ldap_hardcoded_role_mapper" {
			g.Resources[i].Item["role"] = mapClientRoleNames[r.Item["realm_id"].(string)+"_"+r.Item["role"].(string)]
		}

		// Map parent_id to keycloak_group.foo.id Terraform variables for keycloak_group resources
		if _, exist := r.Item["parent_id"]; exist && r.InstanceInfo.Type == "keycloak_group" {
			g.Resources[i].Item["parent_id"] = mapGroupIDs[r.Item["realm_id"].(string)+"_"+r.Item["parent_id"].(string)]
		}

		// Map group_id to keycloak_group.foo.id Terraform variables for keycloak_group_memberships and keycloak_group_roles resources
		if r.InstanceInfo.Type == "keycloak_group_memberships" || r.InstanceInfo.Type == "keycloak_group_roles" {
			g.Resources[i].Item["group_id"] = mapGroupIDs[r.Item["realm_id"].(string)+"_"+r.Item["group_id"].(string)]
		}

		// Map service_account_user_id to keycloak_openid_client.foo.service_account_user_id Terraform variables for service account role resources
		if r.InstanceInfo.Type == "keycloak_openid_client_service_account_role" {
			g.Resources[i].Item["service_account_user_id"] = mapServiceAccountUserIDs[r.Item["realm_id"].(string)+"_"+r.Item["service_account_user_id"].(string)]
			g.Resources[i].Item["role"] = mapClientRoleShortNames[r.Item["realm_id"].(string)+"_"+mapClientNames[r.Item["realm_id"].(string)+"_"+r.Item["client_id"].(string)]+"."+r.Item["role"].(string)]
		}

		// Map client_id attributes to keycloak_openid_client.foo.id Terraform variables for open id mappers resources
		if _, exist := r.Item["client_id"]; exist && (r.InstanceInfo.Type == "keycloak_openid_client_service_account_role" ||
			r.InstanceInfo.Type == "keycloak_openid_audience_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_audience_resolve_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_full_name_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_group_membership_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_hardcoded_claim_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_hardcoded_role_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_script_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_user_attribute_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_user_client_role_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_user_property_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_user_realm_role_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_user_session_note_protocol_mapper" ||
			r.InstanceInfo.Type == "keycloak_openid_client_default_scopes" ||
			r.InstanceInfo.Type == "keycloak_openid_client_optional_scopes" ||
			r.InstanceInfo.Type == "keycloak_role") {
			g.Resources[i].Item["client_id"] = mapClientIDs[r.Item["realm_id"].(string)+"_"+r.Item["client_id"].(string)]
		}

		// Map included_client_audience to keycloak_openid_client.foo.client_id Terraform variables for open id audience mapper resources
		if _, exist := r.Item["included_client_audience"]; exist && r.InstanceInfo.Type == "keycloak_openid_audience_protocol_mapper" {
			g.Resources[i].Item["included_client_audience"] = mapClientClientIDs[r.Item["realm_id"].(string)+"_"+r.Item["included_client_audience"].(string)]
		}

		// Map parent_flow_alias attributes to keycloak_authentication_(sub)flow.foo.alias Terraform variables for authentication subflow and execution resources
		if r.InstanceInfo.Type == "keycloak_authentication_subflow" || r.InstanceInfo.Type == "keycloak_authentication_execution" {
			g.Resources[i].Item["parent_flow_alias"] = mapAuthenticationFlowAliases[r.Item["realm_id"].(string)+"_"+r.Item["parent_flow_alias"].(string)]
		}

		// Map execution_id attributes to keycloak_authentication_execution_config.foo.execution_id Terraform variables for authentication execution config resources
		if r.InstanceInfo.Type == "keycloak_authentication_execution_config" {
			g.Resources[i].Item["execution_id"] = mapAuthenticationExecutionIDs[r.Item["realm_id"].(string)+"_"+r.Item["execution_id"].(string)]
		}

		// Map realm_id attributes to keycloak_realm.foo.id Terraform variables for all the resources (almost all resources have this attribute)
		if _, exist := r.Item["realm_id"]; exist {
			g.Resources[i].Item["realm_id"] = mapRealmIDs[r.Item["realm_id"].(string)]
		}
	}
	return nil
}