From 0d0af3bab25a419c0d56a9efa8f1e6b7e2a96b39 Mon Sep 17 00:00:00 2001 From: Magda Zaremba Date: Thu, 12 Apr 2018 18:49:00 +0200 Subject: [PATCH] Restored realtion between IPAM and network. Custom formatting for IpamSubnetType Change-Id: Iaf9893550dc941b17688b3cc7a9d001521172aef Closes-Bug: #1763449 --- .../buildNumber.properties | 5 +-- .../juniper/contrail/vro/config/Actions.kt | 3 +- .../net/juniper/contrail/vro/config/Config.kt | 16 ++++++++-- .../contrail/vro/config/DisplayConfig.kt | 2 +- .../juniper/contrail/vro/model/Executor.kt | 5 --- .../net/juniper/contrail/vro/model/Finders.kt | 19 ++++++++++++ .../juniper/contrail/vro/model/Relations.kt | 19 ++++++------ .../net/juniper/contrail/vro/model/Utils.kt | 19 +++++++----- .../contrail/vro/AdditionalProperty.kt | 13 ++++++++ .../juniper/contrail/vro/CustomManagedType.kt | 26 ++++++++++++++++ .../net/juniper/contrail/vro/CustomPlugin.kt | 12 ++++---- .../net/juniper/contrail/vro/data.ftl | 11 ++++--- .../vro/format/DisplayNameFormatter.kt | 4 +++ .../vro/generator/model/CustomMappingModel.kt | 12 ++++++-- .../resources/templates/customMapping.ftl | 19 +++++++----- .../main/js/actions/ipamHasAllocationMode.js | 8 ++--- .../js/actions/ipamHasNotAllocationMode.js | 4 +++ .../js/actions/networkHasNotAllocationMode.js | 2 +- .../src/main/js/actions/networkIpamSubnets.js | 4 +-- .../js/actions/subnetsOfVirtualNetwork.js | 6 ++-- .../workflows/removeSubnetFromNetworkIpam.js | 7 +---- .../vro/workflows/custom/CustomActions.kt | 3 +- .../vro/workflows/custom/IpamSubnetType.kt | 4 +++ .../vro/workflows/custom/NetworkIpam.kt | 4 +-- .../vro/workflows/custom/Validation.kt | 10 ++++-- .../vro/workflows/custom/ValidationActions.kt | 29 ++++++++---------- .../vro/workflows/custom/VirtualNetwork.kt | 24 ++++++++------- .../{subnet.png => ipam-subnet-type.png} | Bin 28 files changed, 192 insertions(+), 98 deletions(-) create mode 100644 o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/AdditionalProperty.kt create mode 100644 o11nplugin-contrail-workflows/src/main/js/actions/ipamHasNotAllocationMode.js rename o11nplugin-contrail/src/main/dar/resources/images/{subnet.png => ipam-subnet-type.png} (100%) diff --git a/o11nplugin-contrail-config/buildNumber.properties b/o11nplugin-contrail-config/buildNumber.properties index 65977b5a..85754915 100644 --- a/o11nplugin-contrail-config/buildNumber.properties +++ b/o11nplugin-contrail-config/buildNumber.properties @@ -1,3 +1,4 @@ #maven.buildNumber.plugin properties file -#Wed Apr 11 14:48:29 CEST 2018 -buildNumber=1249 + +#Thu Apr 12 17:03:38 CEST 2018 +buildNumber=1255 diff --git a/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Actions.kt b/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Actions.kt index 4b45b371..667dda3b 100644 --- a/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Actions.kt +++ b/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Actions.kt @@ -30,5 +30,6 @@ val serviceHasInterfaceWithName = "serviceHasInterfaceWithName" val subnetsOfVirtualNetwork = "subnetsOfVirtualNetwork" val templateHasInterfaceWithName = "templateHasInterfaceWithName" val serviceInstanceInterfaceNames = "serviceInstanceInterfaceNames" -val ipamHasAllcationMode = "ipamHasAllocationMode" +val ipamHasAllocationMode = "ipamHasAllocationMode" +val ipamHasNotAllocationMode = "ipamHasNotAllocationMode" val networkHasNotAllcationMode = "networkHasNotAllocationMode" \ No newline at end of file diff --git a/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Config.kt b/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Config.kt index 37cf1809..d63bfe0b 100644 --- a/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Config.kt +++ b/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/Config.kt @@ -10,7 +10,6 @@ import net.juniper.contrail.api.types.* // ktlint-disable no-wildcard-imports val modelClasses = setOf( the(), the(), - the(), the(), the(), the(), @@ -80,6 +79,7 @@ val mandatoryReference = setOf( val nonEditableReference = setOf( pair(), + pair(), pair() ) @@ -100,7 +100,6 @@ val hiddenRoots = setOf( val hiddenRelations = setOf( pair(), - pair(), pair(), pair() ) @@ -109,6 +108,10 @@ val reversedRelations = setOf( pair() ) +val propertiesAsObjects = setOf( + the() +) + private inline fun the() = T::class.java.simpleName @@ -145,6 +148,9 @@ val String.isDirectChild get() = val String.isHiddenRoot get() = hiddenRoots.contains(this) +val String.isApiPropertyAsObject get() = + propertiesAsObjects.contains(this) + fun ObjectClass.isRelationMandatory(child: ObjectClass) = mandatoryReference.containsUnordered(simpleName, child.simpleName) @@ -195,6 +201,12 @@ val Class<*>.isDirectChild get() = val Class<*>.isHiddenRoot get() = simpleName.isHiddenRoot +val Class<*>.isNodeClass get() = + isApiObjectClass || isApiPropertyAsObject + +val Class<*>.isApiPropertyAsObject get() = + simpleName.isApiPropertyAsObject + val ObjectClass.isInternal get() = !hasParents diff --git a/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/DisplayConfig.kt b/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/DisplayConfig.kt index 62621807..9e08d76c 100644 --- a/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/DisplayConfig.kt +++ b/o11nplugin-contrail-config/src/main/kotlin/net/juniper/contrail/vro/config/DisplayConfig.kt @@ -8,7 +8,6 @@ val hiddenProperties = setOf( "parentUuid", "parentType", "idPerms", - "ipamSubnets", "annotations" ) @@ -25,6 +24,7 @@ val String.isHiddenProperty get() = val String.displayedName get() = when (this) { "ipamSubnetMethod" -> "Subnet Method" + "ipamSubnets" -> "Subnets" else -> camelChunks.joinToString(" ") { it.cleanOrRename.capitalize() } } diff --git a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Executor.kt b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Executor.kt index 5aebf3c4..4b540f78 100644 --- a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Executor.kt +++ b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Executor.kt @@ -5,7 +5,6 @@ package net.juniper.contrail.vro.model import net.juniper.contrail.api.types.IpamSubnetType -import net.juniper.contrail.api.types.Subnet import net.juniper.contrail.api.types.VirtualNetwork import net.juniper.contrail.api.types.InstanceIp import net.juniper.contrail.api.types.VirtualMachineInterface @@ -18,10 +17,6 @@ class Executor(private val connection: Connection) { return ipams.asSequence().map { it.attr.ipamSubnets.asSequence().filterNotNull() }.flatten().toList() } - fun IpamSubnetType.subnet(): Subnet? { - return connection.findById(subnetUuid) - } - // InstanceIp should be in 1-1 relation to VMI, so only first element is chosen if it exists fun VirtualMachineInterface.instanceIp(): InstanceIp? = instanceIpBackRefs?.getOrNull(0)?.uuid?.let { connection.findById(it) } diff --git a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Finders.kt b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Finders.kt index afd36375..9ff38b09 100644 --- a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Finders.kt +++ b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Finders.kt @@ -8,6 +8,8 @@ import com.vmware.o11n.sdk.modeldriven.FoundObject import com.vmware.o11n.sdk.modeldriven.ObjectFinder import com.vmware.o11n.sdk.modeldriven.PluginContext import com.vmware.o11n.sdk.modeldriven.Sid +import net.juniper.contrail.api.types.IpamSubnetType +import net.juniper.contrail.api.types.VirtualNetwork import net.juniper.contrail.vro.base.ConnectionRepository import org.springframework.beans.factory.annotation.Autowired @@ -22,4 +24,21 @@ class ConnectionFinder override fun query(ctx: PluginContext, type: String, query: String): List> = connectionRepository.findConnections(query).map { FoundObject(it, it.info.sid) } +} + +class IpamSubnetTypeFinder +@Autowired constructor(private val connectionRepository: ConnectionRepository) : ObjectFinder +{ + override fun assignId(subnet: IpamSubnetType, id: Sid): Sid = + id.with("IpamSubnet", subnet.subnetUuid) + + override fun find(ctx: PluginContext, type: String, id: Sid): IpamSubnetType? { + val connection = connectionRepository.getConnection(id) + val subnetUuid = id.getString("IpamSubnet") ?: return null + val parent = connection?.find(id) ?: return null + return parent.networkIpam.asSequence().flatMap { it.attr.ipamSubnets.asSequence() }.find { it.subnetUuid == subnetUuid } + } + + override fun query(ctx: PluginContext, type: String, query: String): List>? = + null } \ No newline at end of file diff --git a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Relations.kt b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Relations.kt index 5a6c37a1..49b48434 100644 --- a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Relations.kt +++ b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Relations.kt @@ -7,8 +7,8 @@ package net.juniper.contrail.vro.model import com.vmware.o11n.sdk.modeldriven.ObjectRelater import com.vmware.o11n.sdk.modeldriven.PluginContext import com.vmware.o11n.sdk.modeldriven.Sid -import net.juniper.contrail.api.types.Subnet -import net.juniper.contrail.api.types.VirtualNetwork +import net.juniper.contrail.api.types.IpamSubnetType +import net.juniper.contrail.api.types.NetworkIpam import net.juniper.contrail.vro.base.ConnectionRepository import org.springframework.beans.factory.annotation.Autowired @@ -19,14 +19,15 @@ constructor(private val connectionRepository: ConnectionRepository) : ObjectRela connectionRepository.connections } -class VirtualNetworkHasSubnet @Autowired -constructor(private val connectionRepository: ConnectionRepository) : ObjectRelater +class NetworkIpamHasSubnet @Autowired +constructor(private val connectionRepository: ConnectionRepository) : ObjectRelater { - override fun findChildren(ctx: PluginContext, relation: String, parentType: String, id: Sid): List? { + override fun findChildren(ctx: PluginContext, relation: String, parentType: String, id: Sid): List? { + val vnId = id.getString("VirtualNetwork") ?: return null val connection = connectionRepository.getConnection(id) ?: return null - val ipams = connection.find(id)?.networkIpam ?: return null - return ipams.asSequence().map { - it.attr.ipamSubnets.asSequence().map { connection.findById(it.subnetUuid) }.filterNotNull() - }.flatten().toList() + val ipam = connection.find(id) ?: return null + if (ipam.ipamSubnetMethod == "flat-subnet") return null + return ipam.virtualNetworkBackRefs.asSequence().filter { it.uuid == vnId } + .flatMap { it.attr.ipamSubnets.asSequence() }.toList() } } \ No newline at end of file diff --git a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Utils.kt b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Utils.kt index 8295b84d..4becb5eb 100644 --- a/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Utils.kt +++ b/o11nplugin-contrail-core/src/main/kotlin/net/juniper/contrail/vro/model/Utils.kt @@ -121,11 +121,12 @@ class Utils { fun removeSubnetFromVirtualNetwork(network: VirtualNetwork, subnet: String) { val ipams = network.networkIpam ?: return - val index = subnet.split(":")[0].toInt() - val ipamSubnet = ipams.flatMap { it.attr.ipamSubnets.filterNotNull() } [index] + val ipPrefix = parseSubnetIP(subnet) + val ipPrefixLen = parseSubnetPrefix(subnet).toInt() + //first remove subnet from attributes ipams.forEach { - it.attr.ipamSubnets.removeIf { it == ipamSubnet } + it.attr.ipamSubnets.removeIf { it.subnet.ipPrefix == ipPrefix && it.subnet.ipPrefixLen == ipPrefixLen } } //then remove IPAMs if have not subnets ipams.removeIf { @@ -273,12 +274,14 @@ class Utils { return routeString.split(":")[0].toInt() } - fun ipamSubnetToString(ipamSubnet: IpamSubnetType, index: Int): String = ipamSubnet.run { - "$index: CIDR ${subnet.ipPrefix}/${subnet.ipPrefixLen} Gateway $defaultGateway" - } + fun ipamSubnetToString(ipamSubnet: IpamSubnetType?): String? = + ipamSubnet?.run { "${subnet.ipPrefix}/${subnet.ipPrefixLen}" } - fun ipamSubnetStringToIndex(ipamSubnetString: String): Int = - ipamSubnetString.split(":")[0].toInt() + fun removeSubnetFromIpam(cidr: String, ipam : NetworkIpam) { + val ipPrefix = parseSubnetIP(cidr) + val ipPrefixLen = parseSubnetPrefix(cidr).toInt() + ipam.ipamSubnets.subnets.removeIf { it.subnet.ipPrefix == ipPrefix && it.subnet.ipPrefixLen == ipPrefixLen } + } fun lowercase(s: String) = s.toLowerCase() diff --git a/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/AdditionalProperty.kt b/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/AdditionalProperty.kt new file mode 100644 index 00000000..e986750c --- /dev/null +++ b/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/AdditionalProperty.kt @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. + */ + +package net.juniper.contrail.vro + +sealed class AdditionalProperty(val propertyName: String) { + val methodName = "get${propertyName.capitalize()}" +} + +object DisplayNameProperty : AdditionalProperty("displayName") + +val propertyAsObjectNewProperties = listOf(DisplayNameProperty) \ No newline at end of file diff --git a/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomManagedType.kt b/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomManagedType.kt index 5bc30650..1dfc547c 100644 --- a/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomManagedType.kt +++ b/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomManagedType.kt @@ -13,6 +13,8 @@ import net.juniper.contrail.api.ApiObjectBase import net.juniper.contrail.vro.config.ObjectClass import net.juniper.contrail.vro.config.constants.apiTypesPackageName import net.juniper.contrail.vro.config.isApiObjectClass +import net.juniper.contrail.vro.config.isNodeClass +import net.juniper.contrail.vro.config.isApiPropertyAsObject import net.juniper.contrail.vro.config.isApiPropertyClass import net.juniper.contrail.vro.config.isGetter import net.juniper.contrail.vro.config.isHiddenProperty @@ -112,6 +114,9 @@ class CustomManagedType(private val delegate: ManagedType) : ManagedType() { val isObjectClass get() = delegate.modelClass?.isApiObjectClass ?: false + val isNodeClass get() = + delegate.modelClass?.isNodeClass ?: false + val isConnectionChild get() = delegate.modelClass?.let { if (it.isSubclassOf()) { @@ -150,6 +155,13 @@ class CustomManagedType(private val delegate: ManagedType) : ManagedType() { null } ?: emptyList() + val customProperties: List = delegate.modelClass?.run { + if (isApiPropertyAsObject) + propertyAsObjectNewProperties + else + null + } ?: emptyList() + val propertyViews: List = delegate.modelClass?.run { if (isApiObjectClass) methods.asSequence() @@ -168,6 +180,7 @@ class CustomManagedType(private val delegate: ManagedType) : ManagedType() { generateReferenceMethods() generatePropertyMethods() generateReferencePropertiesMethods() + generateCustomProperties() } private fun removeDuplicateMethods() { @@ -197,6 +210,9 @@ class CustomManagedType(private val delegate: ManagedType) : ManagedType() { private fun generateReferenceMethods() = references.forEach { methods.add(it.toManagedMethod()) } + private fun generateCustomProperties() = + customProperties.forEach { methods.add(it.toManagedMethod()) } + private fun generateReferencePropertiesMethods() = referenceProperties.forEach { methods.add(it.toManagedMethod()) } @@ -252,6 +268,16 @@ class CustomManagedType(private val delegate: ManagedType) : ManagedType() { isWrapped = false } + private fun AdditionalProperty.toManagedMethod() = ManagedMethod().apply { + setName(methodName, methodName) + propertyName = this@toManagedMethod.propertyName + originalPropertyName = this@toManagedMethod.propertyName + params = emptyList() + setIsInheritedWrapperMethod(true) + isPropertyReadOnly = true + returns = stringReturnFormalParameter() + } + companion object { fun wrap(type: ManagedType): CustomManagedType { diff --git a/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomPlugin.kt b/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomPlugin.kt index 74349bb0..20bdd8b0 100644 --- a/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomPlugin.kt +++ b/o11nplugin-contrail-custom/src/main/kotlin/net/juniper/contrail/vro/CustomPlugin.kt @@ -8,14 +8,14 @@ import com.vmware.o11n.sdk.modeldrivengen.model.Attribute import com.vmware.o11n.sdk.modeldrivengen.model.ManagedFinder import com.vmware.o11n.sdk.modeldrivengen.model.ManagedType import com.vmware.o11n.sdk.modeldrivengen.model.Plugin -import net.juniper.contrail.vro.config.refWrapperPropertyDisplayName -import net.juniper.contrail.vro.config.cleanedDisplayedProperty -import net.juniper.contrail.vro.config.displayedName -import net.juniper.contrail.vro.config.isRefWrapperProperty +import net.juniper.contrail.vro.config.isApiTypeClass import net.juniper.contrail.vro.config.isCapitalized import net.juniper.contrail.vro.config.isDisplayOnlyProperty -import net.juniper.contrail.vro.config.isModelClass import net.juniper.contrail.vro.config.position +import net.juniper.contrail.vro.config.cleanedDisplayedProperty +import net.juniper.contrail.vro.config.isRefWrapperProperty +import net.juniper.contrail.vro.config.refWrapperPropertyDisplayName +import net.juniper.contrail.vro.config.displayedName class CustomPlugin : Plugin() { @@ -47,7 +47,7 @@ class CustomPlugin : Plugin() { private fun cleanFinders(finders: MutableList) { finders.asSequence() - .filter { it.managedType?.modelClass?.isModelClass ?: false } + .filter { it.managedType?.modelClass?.isApiTypeClass ?: false } .forEach { it.clean() } } diff --git a/o11nplugin-contrail-custom/src/main/resources/net/juniper/contrail/vro/data.ftl b/o11nplugin-contrail-custom/src/main/resources/net/juniper/contrail/vro/data.ftl index 9a039512..a85c0505 100644 --- a/o11nplugin-contrail-custom/src/main/resources/net/juniper/contrail/vro/data.ftl +++ b/o11nplugin-contrail-custom/src/main/resources/net/juniper/contrail/vro/data.ftl @@ -217,10 +217,6 @@ public class ${className} - public String getDisplayName() { - return DisplayNameFormatter.INSTANCE.format(__getTarget()); - } - <#list references as ref> //List returned by this method is read-only. Changes to the list will not be reflected in the state of the object. public java.util.List<${ref.className}_Wrapper> ${ref.pluginMethodName}() { @@ -235,6 +231,13 @@ public class ${className} + <#if nodeClass > + public String getDisplayName() { + return DisplayNameFormatter.INSTANCE.format(__getTarget()); + } + + + <#list propertyViews as property> public String ${property.viewMethodName}() { ${property.propertyType} prop = __getTarget().${property.methodName}(); diff --git a/o11nplugin-contrail-format/src/main/kotlin/net/juniper/contrail/vro/format/DisplayNameFormatter.kt b/o11nplugin-contrail-format/src/main/kotlin/net/juniper/contrail/vro/format/DisplayNameFormatter.kt index e111a9f5..e5b4a1b6 100644 --- a/o11nplugin-contrail-format/src/main/kotlin/net/juniper/contrail/vro/format/DisplayNameFormatter.kt +++ b/o11nplugin-contrail-format/src/main/kotlin/net/juniper/contrail/vro/format/DisplayNameFormatter.kt @@ -6,6 +6,7 @@ package net.juniper.contrail.vro.format import net.juniper.contrail.api.ApiObjectBase import net.juniper.contrail.api.types.FloatingIp +import net.juniper.contrail.api.types.IpamSubnetType import net.juniper.contrail.api.types.Subnet /** @@ -21,4 +22,7 @@ object DisplayNameFormatter { fun format(obj: ApiObjectBase):String? = obj.name + + fun format(obj: IpamSubnetType): String? = + obj.subnet?.let { PropertyFormatter.format(it) } } \ No newline at end of file diff --git a/o11nplugin-contrail-generator/src/main/kotlin/net/juniper/contrail/vro/generator/model/CustomMappingModel.kt b/o11nplugin-contrail-generator/src/main/kotlin/net/juniper/contrail/vro/generator/model/CustomMappingModel.kt index 2051fa5d..338f4a98 100644 --- a/o11nplugin-contrail-generator/src/main/kotlin/net/juniper/contrail/vro/generator/model/CustomMappingModel.kt +++ b/o11nplugin-contrail-generator/src/main/kotlin/net/juniper/contrail/vro/generator/model/CustomMappingModel.kt @@ -9,11 +9,12 @@ import net.juniper.contrail.vro.config.PropertyClass import net.juniper.contrail.vro.config.folderName import net.juniper.contrail.vro.config.pluginName import net.juniper.contrail.vro.config.ProjectInfo +import net.juniper.contrail.vro.config.isApiPropertyAsObject data class CustomMappingModel ( val findableClasses: List, val rootClasses: List, - val propertyClassNames: List, + val propertyClasses: List, val relations: List, val forwardRelations: List, val nestedRelations: List, @@ -26,6 +27,13 @@ data class ClassInfoModel( val folderName: String ) +data class PropertyInfo(val simpleName: String) { + val isPropertyAsObject : Boolean get() = + simpleName.isApiPropertyAsObject +} + +fun Class<*>.toPropertyInfoClass() = PropertyInfo(simpleName) + fun Class<*>.toClassInfoModel() = ClassInfoModel( simpleName, pluginName, @@ -43,7 +51,7 @@ fun generateCustomMappingModel( ) = CustomMappingModel( objectClasses.map { it.toClassInfoModel() }, rootClasses.map { it.toClassInfoModel() }, - propertyClasses.map { it.simpleName }, + propertyClasses.map { it.toPropertyInfoClass() }, relations.map { it.toRelationModel() }, forwardRelations, nestedRelations.map { it.toNestedRelationModel() }, diff --git a/o11nplugin-contrail-generator/src/main/resources/templates/customMapping.ftl b/o11nplugin-contrail-generator/src/main/resources/templates/customMapping.ftl index caf50b3d..9afe2d11 100644 --- a/o11nplugin-contrail-generator/src/main/resources/templates/customMapping.ftl +++ b/o11nplugin-contrail-generator/src/main/resources/templates/customMapping.ftl @@ -72,8 +72,14 @@ class CustomMapping: AbstractMapping() { .withIcon(findItemIcon<${klass.simpleName}>()) - <#list propertyClassNames as klass> - wrap(${klass}::class.java) + <#list propertyClasses as klass> + wrap(${klass.simpleName}::class.java) + <#if klass.propertyAsObject> + .rename(renamePolicy) + .andFind() + .using(${klass.simpleName}Finder::class.java) + .withIcon(findItemIcon<${klass.simpleName}>()) + <#list nestedRelations as relation> @@ -92,11 +98,10 @@ class CustomMapping: AbstractMapping() { .using(RootHasConnections::class.java) .`as`("RootHasConnections") - relate(VirtualNetwork::class.java) - .to(Subnet::class.java) - .using(VirtualNetworkHasSubnet::class.java) - .`as`("VirtualNetworkToSubnet") - .`in`(FolderDef(folderName("Subnets", "VirtualNetwork", "Subnet"), findFolderIcon())) + relate(NetworkIpam::class.java) + .to(IpamSubnetType::class.java) + .using(NetworkIpamHasSubnet::class.java) + .`as`("NetworkIpamHasSubnet") <#list rootClasses as rootClass> relate(Connection::class.java) diff --git a/o11nplugin-contrail-workflows/src/main/js/actions/ipamHasAllocationMode.js b/o11nplugin-contrail-workflows/src/main/js/actions/ipamHasAllocationMode.js index 00523a9d..a1480d3a 100644 --- a/o11nplugin-contrail-workflows/src/main/js/actions/ipamHasAllocationMode.js +++ b/o11nplugin-contrail-workflows/src/main/js/actions/ipamHasAllocationMode.js @@ -1,8 +1,4 @@ -if (!networkIpam || !mode || !expected || ((networkIpam.ipamSubnetMethod == mode) == expected)){ +if (!networkIpam || !mode || (networkIpam.ipamSubnetMethod == mode)){ return null; } -var not = "" -if (!expected){ - not = "not " -} -return "Select a network IPAM with " + not + mode + " allocation mode"; \ No newline at end of file +return "Select a network IPAM with " + mode + " allocation mode"; \ No newline at end of file diff --git a/o11nplugin-contrail-workflows/src/main/js/actions/ipamHasNotAllocationMode.js b/o11nplugin-contrail-workflows/src/main/js/actions/ipamHasNotAllocationMode.js new file mode 100644 index 00000000..f041b932 --- /dev/null +++ b/o11nplugin-contrail-workflows/src/main/js/actions/ipamHasNotAllocationMode.js @@ -0,0 +1,4 @@ +if (!networkIpam || !mode || !(networkIpam.ipamSubnetMethod == mode)){ + return null; +} +return "Select a network IPAM with allocation mode other than " + mode; \ No newline at end of file diff --git a/o11nplugin-contrail-workflows/src/main/js/actions/networkHasNotAllocationMode.js b/o11nplugin-contrail-workflows/src/main/js/actions/networkHasNotAllocationMode.js index 7910fb96..cc2152e8 100644 --- a/o11nplugin-contrail-workflows/src/main/js/actions/networkHasNotAllocationMode.js +++ b/o11nplugin-contrail-workflows/src/main/js/actions/networkHasNotAllocationMode.js @@ -1,4 +1,4 @@ if (!virtualNetwork || !mode || (virtualNetwork.addressAllocationMode != mode)){ return null; } -return "Select virtual network with not " + mode + " allocation mode"; \ No newline at end of file +return "Select virtual network with allocation mode other than " + mode; \ No newline at end of file diff --git a/o11nplugin-contrail-workflows/src/main/js/actions/networkIpamSubnets.js b/o11nplugin-contrail-workflows/src/main/js/actions/networkIpamSubnets.js index 62bbcb5c..5293c001 100644 --- a/o11nplugin-contrail-workflows/src/main/js/actions/networkIpamSubnets.js +++ b/o11nplugin-contrail-workflows/src/main/js/actions/networkIpamSubnets.js @@ -3,7 +3,7 @@ var subnets = parent.getIpamSubnets(); if (!subnets) return null; var subnetList = subnets.getSubnets(); -subnetList.forEach(function (value, index) { - actionResult.push(ContrailUtils.ipamSubnetToString(value, index)); +subnetList.forEach(function (value) { + actionResult.push(ContrailUtils.ipamSubnetToString(value)); }); return actionResult; \ No newline at end of file diff --git a/o11nplugin-contrail-workflows/src/main/js/actions/subnetsOfVirtualNetwork.js b/o11nplugin-contrail-workflows/src/main/js/actions/subnetsOfVirtualNetwork.js index 82f00513..e16ec19c 100644 --- a/o11nplugin-contrail-workflows/src/main/js/actions/subnetsOfVirtualNetwork.js +++ b/o11nplugin-contrail-workflows/src/main/js/actions/subnetsOfVirtualNetwork.js @@ -1,8 +1,8 @@ var actionResult = new Array(); var subnets = parent.subnets(); -if (!subnets) return null; +if (!subnets) return actionResult; -subnets.forEach(function (value, index) { - actionResult.push(ContrailUtils.ipamSubnetToString(value, index)); +subnets.forEach(function (value) { + actionResult.push(ContrailUtils.ipamSubnetToString(value)); }); return actionResult; diff --git a/o11nplugin-contrail-workflows/src/main/js/workflows/removeSubnetFromNetworkIpam.js b/o11nplugin-contrail-workflows/src/main/js/workflows/removeSubnetFromNetworkIpam.js index dea11192..a03236e1 100644 --- a/o11nplugin-contrail-workflows/src/main/js/workflows/removeSubnetFromNetworkIpam.js +++ b/o11nplugin-contrail-workflows/src/main/js/workflows/removeSubnetFromNetworkIpam.js @@ -1,8 +1,3 @@ -var index = ContrailUtils.ipamSubnetStringToIndex(ipamSubnet); - -var list = item.getIpamSubnets().getSubnets(); -list.splice(index, 1); - -item.setIpamSubnets(new ContrailIpamSubnets(list)); +ContrailUtils.removeSubnetFromIpam(ipamSubnet, item); item.update(); \ No newline at end of file diff --git a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/CustomActions.kt b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/CustomActions.kt index 0107b6d7..c29949de 100644 --- a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/CustomActions.kt +++ b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/CustomActions.kt @@ -31,6 +31,7 @@ fun loadCustomActions(version: String, packageName: String): List = muta this += serviceHasInterfaceWithNameAction(version, packageName) this += templateHasInterfaceWithNameAction(version, packageName) this += networkIpamSubnets(version, packageName) - this += ipamHasAllcationModeAction(version, packageName) + this += ipamHasAllocationModeAction(version, packageName) + this += ipamHasNotAllocationModeAction(version, packageName) this += networkHasNotAllcationModeAction(version, packageName) } \ No newline at end of file diff --git a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/IpamSubnetType.kt b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/IpamSubnetType.kt index 5b5d0897..5753f6e3 100644 --- a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/IpamSubnetType.kt +++ b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/IpamSubnetType.kt @@ -1,3 +1,7 @@ +/* + * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. + */ + package net.juniper.contrail.vro.workflows.custom import net.juniper.contrail.api.types.IpamSubnetType diff --git a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/NetworkIpam.kt b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/NetworkIpam.kt index 8ee26eca..e0360a5d 100644 --- a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/NetworkIpam.kt +++ b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/NetworkIpam.kt @@ -28,7 +28,7 @@ internal fun createNetworkIpamSubnetWorkflow(schema: Schema): WorkflowDefinition parameter(parent, reference()) { description = "IPAM this subnet belongs to." mandatory = true - validWhen = ipamHasAllocationMode(flat, true) + validWhen = ipamHasAllocationMode(flat) } } ipamSubnetParameters(schema) @@ -42,7 +42,7 @@ internal fun removeNetworkIpamSubnetWorkflow(schema: Schema): WorkflowDefinition parameter(item, reference()) { description = relationDescription(schema) mandatory = true - validWhen = ipamHasAllocationMode(flat, true) + validWhen = ipamHasAllocationMode(flat) } parameter("ipamSubnet", string) { visibility = WhenNonNull(item) diff --git a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/Validation.kt b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/Validation.kt index a4531344..2d2e9d39 100644 --- a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/Validation.kt +++ b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/Validation.kt @@ -15,7 +15,8 @@ import net.juniper.contrail.vro.config.isSingleAddressNetworkPolicyRule import net.juniper.contrail.vro.config.isSingleAddressSecurityGroupRule import net.juniper.contrail.vro.config.areValidCommunityAttributes import net.juniper.contrail.vro.config.networkHasNotAllcationMode -import net.juniper.contrail.vro.config.ipamHasAllcationMode +import net.juniper.contrail.vro.config.ipamHasAllocationMode +import net.juniper.contrail.vro.config.ipamHasNotAllocationMode import net.juniper.contrail.vro.workflows.dsl.BasicParameterBuilder import net.juniper.contrail.vro.workflows.dsl.ReferenceParameterBuilder @@ -25,8 +26,11 @@ fun BasicParameterBuilder.isSubnet() = fun ReferenceParameterBuilder.networkHasNotAllocationMode(mode: String) = validationActionCallTo(networkHasNotAllcationMode).string(mode) -fun ReferenceParameterBuilder.ipamHasAllocationMode(mode: String, expected: Boolean) = - validationActionCallTo(ipamHasAllcationMode).string(mode).boolean(expected) +fun ReferenceParameterBuilder.ipamHasAllocationMode(mode: String) = + validationActionCallTo(ipamHasAllocationMode).string(mode) + +fun ReferenceParameterBuilder.ipamHasNotAllocationMode(mode: String) = + validationActionCallTo(ipamHasNotAllocationMode).string(mode) fun BasicParameterBuilder.isCidr() = validationActionCallTo(isValidCidr) diff --git a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/ValidationActions.kt b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/ValidationActions.kt index 51081473..2e576b7f 100644 --- a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/ValidationActions.kt +++ b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/ValidationActions.kt @@ -21,7 +21,8 @@ import net.juniper.contrail.vro.config.isValidSubnet import net.juniper.contrail.vro.config.serviceHasInterfaceWithName import net.juniper.contrail.vro.config.templateHasInterfaceWithName import net.juniper.contrail.vro.config.networkHasNotAllcationMode -import net.juniper.contrail.vro.config.ipamHasAllcationMode +import net.juniper.contrail.vro.config.ipamHasAllocationMode +import net.juniper.contrail.vro.config.ipamHasNotAllocationMode import net.juniper.contrail.vro.workflows.dsl.ofType import net.juniper.contrail.vro.workflows.model.any import net.juniper.contrail.vro.workflows.model.array @@ -92,29 +93,25 @@ val areValidCommunityAttributesAction = ActionDefinition ( val serviceHasInterfaceWithNameAction = ActionDefinition( name = serviceHasInterfaceWithName, resultType = boolean, - parameters = listOf( - "serviceInstance" ofType reference(), - "name" ofType string - ) + parameters = listOf("serviceInstance" ofType reference(), "name" ofType string) ) val templateHasInterfaceWithNameAction = ActionDefinition( name = templateHasInterfaceWithName, resultType = boolean, - parameters = listOf( - "serviceTemplate" ofType reference(), - "name" ofType string - ) + parameters = listOf("serviceTemplate" ofType reference(), "name" ofType string) ) -val ipamHasAllcationModeAction = ActionDefinition( - name = ipamHasAllcationMode, +val ipamHasAllocationModeAction = ActionDefinition( + name = ipamHasAllocationMode, resultType = string, - parameters = listOf( - "networkIpam" ofType reference(), - "mode" ofType string, - "expected" ofType boolean - ) + parameters = listOf("networkIpam" ofType reference(), "mode" ofType string) +) + +val ipamHasNotAllocationModeAction = ActionDefinition( + name = ipamHasNotAllocationMode, + resultType = string, + parameters = listOf("networkIpam" ofType reference(), "mode" ofType string) ) val networkHasNotAllcationModeAction = ActionDefinition( diff --git a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/VirtualNetwork.kt b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/VirtualNetwork.kt index 7d1fbbc2..b71165a9 100644 --- a/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/VirtualNetwork.kt +++ b/o11nplugin-contrail-workflows/src/main/kotlin/net/juniper/contrail/vro/workflows/custom/VirtualNetwork.kt @@ -19,10 +19,12 @@ import net.juniper.contrail.vro.workflows.dsl.asBrowserRoot import net.juniper.contrail.vro.workflows.model.reference import net.juniper.contrail.vro.workflows.model.string import net.juniper.contrail.vro.workflows.schema.Schema +import net.juniper.contrail.vro.workflows.util.parentDescriptionInCreateRelation import net.juniper.contrail.vro.workflows.util.addRelationWorkflowName import net.juniper.contrail.vro.workflows.util.childDescriptionInCreateRelation -import net.juniper.contrail.vro.workflows.util.parentDescriptionInCreateRelation -import net.juniper.contrail.vro.workflows.util.relationDescription +import net.juniper.contrail.vro.workflows.util.removeRelationWorkflowName +import net.juniper.contrail.vro.workflows.util.parentDescriptionInRemoveRelation +import net.juniper.contrail.vro.workflows.util.childDescriptionInRemoveRelation val flatOnly = "flat-subnet-only" val userDefinedOnly = "user-defined-subnet-only" @@ -58,7 +60,7 @@ internal fun createSubnetWorkflow(schema: Schema): WorkflowDefinition { parameter("ipam", reference()) { description = "IPAM this subnet uses." mandatory = true - validWhen = ipamHasAllocationMode(flat, false) + validWhen = ipamHasNotAllocationMode(flat) } } ipamSubnetParameters(schema) @@ -67,19 +69,19 @@ internal fun createSubnetWorkflow(schema: Schema): WorkflowDefinition { internal fun addFlatIpamWorkflow(schema: Schema): WorkflowDefinition { - val workflowName = "Add network IPAM to virtual network" + val workflowName = schema.addRelationWorkflowName() return customWorkflow(workflowName).withScriptFile("addFlatIpamToNetwork") { step("References") { parameter(parent, reference()) { - description = "Virtual network to which network IPAM should be added to." + description = schema.parentDescriptionInCreateRelation() mandatory = true validWhen = networkHasNotAllocationMode(userDefinedOnly) } parameter("ipam", reference()) { - description = relationDescription(schema) + description = schema.childDescriptionInCreateRelation() mandatory = true - validWhen = ipamHasAllocationMode(flat, true) + validWhen = ipamHasAllocationMode(flat) } } } @@ -87,22 +89,22 @@ internal fun addFlatIpamWorkflow(schema: Schema): WorkflowDefinition { internal fun removeFlatIpamWorkflow(): WorkflowDefinition { - val workflowName = "Remove network IPAM from virtual network" + val workflowName = removeRelationWorkflowName() return customWorkflow(workflowName).withScriptFile("removeFlatIpamFromNetwork") { step("References") { parameter(parent, reference()) { - description = "Virtual network which network IPAM should be removed from." + description = parentDescriptionInRemoveRelation() mandatory = true validWhen = networkHasNotAllocationMode(userDefinedOnly) } parameter("ipam", reference()) { - description = "Network IPAM to be removed" + description = childDescriptionInRemoveRelation() visibility = WhenNonNull(parent) browserRoot = parent.asBrowserRoot() mandatory = true listedBy = actionCallTo(propertyValue).parameter(parent).string(asForwardRef()) - validWhen = ipamHasAllocationMode(flat, true) + validWhen = ipamHasAllocationMode(flat) } } } diff --git a/o11nplugin-contrail/src/main/dar/resources/images/subnet.png b/o11nplugin-contrail/src/main/dar/resources/images/ipam-subnet-type.png similarity index 100% rename from o11nplugin-contrail/src/main/dar/resources/images/subnet.png rename to o11nplugin-contrail/src/main/dar/resources/images/ipam-subnet-type.png