Skip to content

Commit

Permalink
Add workflows for managing AddressGroup subnets.
Browse files Browse the repository at this point in the history
Change-Id: I6bb6a494d2f1e5097aa3eb27e7f520ff50b7e1c9
Partial-Bug: #1772594
(cherry picked from commit 84f4434)
  • Loading branch information
danieljasinski committed Jun 6, 2018
1 parent 0eead5a commit 876ef99
Show file tree
Hide file tree
Showing 55 changed files with 565 additions and 125 deletions.
Expand Up @@ -2,6 +2,8 @@
* Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
*/

@file:JvmName("Actions")

package net.juniper.contrail.vro.config

val actionPackage = globalProjectInfo.workflowPackage
Expand All @@ -20,7 +22,9 @@ val isSingleAddressNetworkPolicyRule = "isSingleAddressNetworkPolicyRule"
val isSingleAddressSecurityGroupRule = "isSingleAddressSecurityGroupRule"
val networkOfServiceInterface = "networkOfServiceInterface"
val networkPolicyRules = "networkPolicyRules"
val virtualNetworkSubnets = "virtualNetworkSubnets"
val networkIpamSubnets = "networkIpamSubnets"
val addressGroupSubnets = "addressGroupSubnets"
val parentConnection = "parentConnection"
val portsForServiceInterface = "portsForServiceInterface"
val isValidMac = "isValidMac"
Expand All @@ -30,7 +34,6 @@ val propertyNotNull = "propertyNotNull"
val propertyValue = "propertyValue"
val routeTableRoutes = "routeTableRoutes"
val serviceHasInterfaceWithName = "serviceHasInterfaceWithName"
val subnetsOfVirtualNetwork = "subnetsOfVirtualNetwork"
val templateHasInterfaceWithName = "templateHasInterfaceWithName"
val serviceInstanceInterfaceNames = "serviceInstanceInterfaceNames"
val ipamHasAllocationMode = "ipamHasAllocationMode"
Expand Down
Expand Up @@ -2,6 +2,8 @@
* Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
*/

@file:JvmName("Constants")

package net.juniper.contrail.vro.config.constants

val Contrail = "Contrail"
Expand All @@ -20,6 +22,7 @@ val item = "item"
val id = "id"
val ingress = "ingress"
val egress = "egress"
val subnet = "subnet"

val maxOtherInterfacesSupported = 8
val supportedOtherInterfaces = (0 until maxOtherInterfacesSupported).map { "other$it" }
Expand Down
Expand Up @@ -377,7 +377,7 @@ open class NetworkPolicyRulePropertyExecutor(private val connection: Connection)
useDstAddressType: Boolean
): String? {
val address = extractAddressType(ruleString, useDstAddressType)
return utils.formatSubnet(address.subnet)
return utils.subnetToString(address.subnet)
}

private fun NetworkPolicy.ruleAddressPropertyNetworkType(
Expand Down
Expand Up @@ -74,7 +74,7 @@ class SecurityGroupRulePropertyExecutor(private val connection: Connection) : Se
ruleString: String
): String? {
val address = extractAddress(ruleString)
return utils.formatSubnet(address.subnet)
return utils.subnetToString(address.subnet)
}

override fun SecurityGroup.rulePropertyAddressSecurityGroup(
Expand Down
Expand Up @@ -4,6 +4,7 @@

package net.juniper.contrail.vro.model

import net.juniper.contrail.api.types.AddressGroup
import net.juniper.contrail.api.types.AddressType
import net.juniper.contrail.api.types.NetworkIpam
import net.juniper.contrail.api.types.NetworkPolicy
Expand Down Expand Up @@ -191,12 +192,6 @@ class Utils {
return portNumber
}

fun formatSubnet(subnet: SubnetType?): String? {
if (subnet == null) return null
if (subnet.ipPrefix == null || subnet.ipPrefixLen == null) return null
return subnet.run { "$ipPrefix/$ipPrefixLen" }
}

fun parseSubnet(def: String?): SubnetType? {
if (def == null || def.isBlank()) return null
val cleaned = def.trim()
Expand Down Expand Up @@ -285,15 +280,27 @@ class Utils {
return routeString.split(":")[0].toInt()
}

fun subnetToString(subnet: SubnetType?): String? {
if (subnet == null) return null
if (subnet.ipPrefix == null || subnet.ipPrefixLen == null) return null
return subnet.run { "$ipPrefix/$ipPrefixLen" }
}

fun ipamSubnetToString(ipamSubnet: IpamSubnetType?): String? =
ipamSubnet?.run { "${subnet.ipPrefix}/${subnet.ipPrefixLen}" }
subnetToString(ipamSubnet?.subnet)

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 removeSubnetFromAddressGroup(cidr: String, addressGroup : AddressGroup) {
val ipPrefix = parseSubnetIP(cidr)
val ipPrefixLen = parseSubnetPrefix(cidr).toInt()
addressGroup.prefix.subnet.removeIf { it.ipPrefix == ipPrefix && it.ipPrefixLen == ipPrefixLen }
}

fun lowercase(s: String) =
s.toLowerCase()

Expand Down
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
*/

package net.juniper.contrail.vro

import com.vmware.o11n.sdk.modeldrivengen.code.CodeGeneratorConfig
Expand Down
Expand Up @@ -4,19 +4,16 @@

package net.juniper.contrail.vro.tests.actions

import net.juniper.contrail.vro.tests.ScriptTestEngine
import spock.lang.Specification
import static net.juniper.contrail.vro.workflows.custom.Custom.loadCustomActions
import net.juniper.contrail.vro.tests.scripts.ScriptSpec

import static net.juniper.contrail.vro.tests.JsTesterKt.constantsName
import static net.juniper.contrail.vro.tests.JsTesterKt.utilsName

abstract class ActionSpec extends Specification {
static def dummyVersion = "1.0"
static def dummyPackage = "contrail"
static def actions = loadCustomActions(dummyVersion, dummyPackage)
def engine = new ScriptTestEngine()
abstract class ActionSpec extends ScriptSpec {

def setup() {
engine.addToContext(utilsName)
engine.addToContext(constantsName)
}
}

Expand Down
@@ -0,0 +1,65 @@
package net.juniper.contrail.vro.tests.actions

import net.juniper.contrail.api.types.AddressGroup
import net.juniper.contrail.api.types.SubnetListType
import net.juniper.contrail.api.types.SubnetType
import static net.juniper.contrail.vro.model.UtilsKt.utils
import static net.juniper.contrail.vro.config.Actions.addressGroupSubnets

class AddressGroupSubnetsSpec extends ActionSpec {
def action = actionFromScript(addressGroupSubnets)

def "null address group results in null" () {
given: "null address group"
def addressGroup = null

when: "retrieved subnet list"
def result = invokeAction(action, addressGroup)

then: "resulting list is null"
result == null
}

def "empty address group results in null" () {
given: "empty address group"
def addressGroup = new AddressGroup()

when: "retrieved subnet list"
def result = invokeAction(action, addressGroup)

then: "resulting list is null"
result == null
}

def "address group with empty subnet list results in empty list" () {
given: "empty address group"
def addressGroup = new AddressGroup()
def subnetListType = new SubnetListType()
addressGroup.prefix = subnetListType
subnetListType.subnet = new ArrayList<>()

when: "retrieved subnet list"
def result = invokeAction(action, addressGroup) as List<String>

then: "resulting list is empty"
result.isEmpty()
}

def "address group with single subnet results in list with single formatted subnet" () {
given: "address group with single subnet"
def addressGroup = new AddressGroup()
def subnetListType = new SubnetListType()
addressGroup.prefix = subnetListType
def somePrefix = "1.2.3.4"
def somePrefixLen = 16
def subnet = new SubnetType(somePrefix, somePrefixLen)
subnetListType.addSubnet(subnet)

when: "retrieved subnet list"
def result = invokeAction(action, addressGroup) as List<String>

then: "resulting list has one formatted element"
result.size() == 1
result[0] == utils.subnetToString(subnet)
}
}
Expand Up @@ -4,10 +4,10 @@

package net.juniper.contrail.vro.tests.actions

import static net.juniper.contrail.vro.config.ActionsKt.isValidAllocactionPool
import static net.juniper.contrail.vro.config.Actions.isValidAllocactionPool

class AllocationPoolValidationSpec extends ActionSpec {
def validatePool = engine.getFunctionFromActionScript(actions, isValidAllocactionPool)
def validatePool = actionFromScript(isValidAllocactionPool)
def allocationValidationMessage = "e.g. 192.168.2.3-192.168.2.10 <enter>... and IPs should be from CIDR"

def "validating allocation pool with pools and cidr not defined should pass" () {
Expand Down
Expand Up @@ -4,10 +4,10 @@

package net.juniper.contrail.vro.tests.actions

import static net.juniper.contrail.vro.config.ActionsKt.isValidSubnet
import static net.juniper.contrail.vro.config.Actions.isValidSubnet

class CidrValidationSpec extends ActionSpec {
def validateCidr = engine.getFunctionFromActionScript(actions, isValidSubnet)
def validateCidr = actionFromScript(isValidSubnet)
def cidrValidationMessage = "Enter valid IPv4 or IPv6 Subnet/Mask"

def "validating cidr not defined should pass" () {
Expand Down
Expand Up @@ -4,10 +4,10 @@

package net.juniper.contrail.vro.tests.actions

import static net.juniper.contrail.vro.config.ActionsKt.isFreeInCidr
import static net.juniper.contrail.vro.config.Actions.isFreeInCidr

class FreeInCidrValidationSpec extends ActionSpec {
def validateFreeIp = engine.getFunctionFromActionScript(actions, isFreeInCidr)
def validateFreeIp = actionFromScript(isFreeInCidr)
def freeIpMsg = "Default Gateway IP must be in CIDR and not be in allocation pools or be the same as DNS server IP"

def "validating free ip in cidr with all parameters not defined should pass" () {
Expand Down
Expand Up @@ -4,10 +4,10 @@

package net.juniper.contrail.vro.tests.actions

import static net.juniper.contrail.vro.config.ActionsKt.isInCidr
import static net.juniper.contrail.vro.config.Actions.isInCidr

class InCidrValidationSpec extends ActionSpec {
def validateIp = engine.getFunctionFromActionScript(actions, isInCidr)
def validateIp = actionFromScript(isInCidr)
def ipValidationMessage = "IP must be in defined CIDR"

def "validating ip with ip and cidr not defined should pass" () {
Expand Down
Expand Up @@ -4,10 +4,10 @@

package net.juniper.contrail.vro.tests.actions

import static net.juniper.contrail.vro.config.ActionsKt.isValidIp
import static net.juniper.contrail.vro.config.Actions.isValidIp

class IpValidationSpec extends ActionSpec {
def validateIp = engine.getFunctionFromActionScript(actions, isValidIp)
def validateIp = actionFromScript(isValidIp)
def ipValidationMessage = "Enter valid IPv4 or IPv6 Address"

def "validating ip not defined should pass" () {
Expand Down
@@ -0,0 +1,69 @@
package net.juniper.contrail.vro.tests.actions

import net.juniper.contrail.api.types.IpamSubnetType
import net.juniper.contrail.api.types.IpamSubnets
import net.juniper.contrail.api.types.NetworkIpam
import net.juniper.contrail.api.types.SubnetType

import static net.juniper.contrail.vro.config.Actions.networkIpamSubnets
import static net.juniper.contrail.vro.model.UtilsKt.utils

class NetworkIpamSubnetsSpec extends ActionSpec {
def action = actionFromScript(networkIpamSubnets)

def "null network IPAM results in null" () {
given: "null address group"
def ipam = null

when: "retrieved subnet list"
def result = invokeAction(action, ipam)

then: "resulting list is null"
result == null
}

def "empty IPAM results in null" () {
given: "empty IPAM"
def ipam = new NetworkIpam()

when: "retrieved subnet list"
def result = invokeAction(action, ipam)

then: "resulting list is null"
result == null
}

def "IPAM with empty subnet list results in empty list" () {
given: "empty IPAM"
def ipam = new NetworkIpam()
def ipamSubnets = new IpamSubnets()
ipam.ipamSubnets = ipamSubnets
ipamSubnets.subnets = new ArrayList<>()

when: "retrieved subnet list"
def result = invokeAction(action, ipam) as List<String>

then: "resulting list is empty"
result.isEmpty()
}

def "IPAM with single subnet results in list with single formatted subnet" () {
given: "IPAM with single subnet"
def ipam = new NetworkIpam()
def ipamSubnets = new IpamSubnets()
ipam.ipamSubnets = ipamSubnets
def somePrefix = "1.2.3.4"
def somePrefixLen = 16
def ipamSubnet = new IpamSubnetType()
def subnet = new SubnetType(somePrefix, somePrefixLen)
ipamSubnet.setSubnet(subnet)
ipamSubnets.addSubnets(ipamSubnet)

when: "retrieved subnet list"
def result = invokeAction(action, ipam) as List<String>

then: "resulting list has one formatted element"
result.size() == 1
result[0] == utils.ipamSubnetToString(ipamSubnet)
}
}

0 comments on commit 876ef99

Please sign in to comment.