Skip to content

Commit

Permalink
Add firewall rule workflows
Browse files Browse the repository at this point in the history
Change-Id: I879b19931afdd88c875af88bf75ab6df70b6b8ce
Partial-Bug: #1772594
  • Loading branch information
IridiumOxide committed Jun 8, 2018
1 parent 4baf3cd commit 9db7112
Show file tree
Hide file tree
Showing 13 changed files with 448 additions and 18 deletions.
4 changes: 2 additions & 2 deletions o11nplugin-contrail-config/buildNumber.properties
@@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file
#Fri May 18 13:04:09 CEST 2018
buildNumber=1354
#Wed Jun 06 17:32:42 CEST 2018
buildNumber=1423
Expand Up @@ -76,7 +76,8 @@ val customCreateWorkflows = setOf(
the<PortTuple>(),
the<PolicyManagement>(),
the<Tag>(),
the<TagType>()
the<TagType>(),
the<FirewallRule>()
)

val customEditWorkflows = setOf(
Expand All @@ -86,7 +87,8 @@ val customEditWorkflows = setOf(
the<ServiceTemplate>(),
the<ServiceInstance>(),
the<PortTuple>(),
the<PolicyManagement>()
the<PolicyManagement>(),
the<FirewallRule>()
)

val customDeleteWorkflows = setOf(
Expand Down Expand Up @@ -133,7 +135,10 @@ val hiddenRelations = setOf(
pair<VirtualMachineInterface, VirtualMachine>(),
pair<ServiceTemplate, ServiceApplianceSet>(),
pair<Project, PolicyManagement>(),
pair<Tag, TagType>()
pair<Tag, TagType>(),
pair<FirewallRule, AddressGroup>(),
pair<FirewallRule, ServiceGroup>(),
pair<FirewallRule, VirtualNetwork>()
)

val tagRelations = setOf(
Expand All @@ -152,6 +157,10 @@ val reversedRelations = setOf(
pair<FloatingIp, VirtualMachineInterface>()
)

val readUponQuery = setOf(
the<FirewallRule>()
)

private inline fun <reified T> the() =
T::class.java.simpleName

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

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

enum class EndpointType(val value: String) {
None("none"),
Tag("tag"),
AddressGroup("address group"),
VirtualNetwork("virtual network"),
AnyWorkload("any workload")
}

enum class ServiceType(val value: String) {
Manual("manual"),
Reference("reference")
}
Expand Up @@ -17,7 +17,8 @@ import net.juniper.contrail.api.types.TagType
// They are combined using inheritance so that their functions become Executor's methods.
class Executor(private val connection: Connection) :
SecurityGroupRuleProperties by SecurityGroupRulePropertyExecutor(connection),
NetworkPolicyRuleProperties by NetworkPolicyRulePropertyExecutor(connection) {
NetworkPolicyRuleProperties by NetworkPolicyRulePropertyExecutor(connection),
FirewallRuleComplexProperties by FirewallRuleComplexPropertyExecutor(connection) {
fun VirtualNetwork.subnets(): List<IpamSubnetType> {
val ipams = networkIpam ?: return emptyList()
return ipams.asSequence().map { it.attr.ipamSubnets.asSequence().filterNotNull() }.flatten().toList()
Expand Down
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
*/

package net.juniper.contrail.vro.model

import net.juniper.contrail.api.types.AddressGroup
import net.juniper.contrail.api.types.FirewallRule
import net.juniper.contrail.api.types.FirewallRuleEndpointType
import net.juniper.contrail.api.types.Tag
import net.juniper.contrail.api.types.VirtualNetwork
import net.juniper.contrail.vro.config.constants.EndpointType
import net.juniper.contrail.vro.config.constants.ServiceType

interface FirewallRuleComplexProperties {
fun FirewallRule.endpointType(endpointNumber: Int): String?
fun FirewallRule.serviceType(): String?
fun FirewallRule.endpointNetwork(endpointNumber: Int): VirtualNetwork?
fun FirewallRule.endpointAddressGroup(endpointNumber: Int): AddressGroup?
fun FirewallRule.endpointTags(endpointNumber: Int): List<Tag?>?
fun FirewallRule.serviceSrcPorts(): String?
fun FirewallRule.serviceDstPorts(): String?
}

open class FirewallRuleComplexPropertyExecutor(private val connection: Connection) : FirewallRuleComplexProperties {
override fun FirewallRule.endpointType(endpointNumber: Int): String? =
endpoint(endpointNumber)?.type()

override fun FirewallRule.serviceType(): String? = when {
serviceGroup[0] != null -> ServiceType.Reference.value
else -> ServiceType.Manual.value
}

override fun FirewallRule.endpointNetwork(endpointNumber: Int): VirtualNetwork? {
val networkFqn = endpoint(endpointNumber)?.virtualNetwork ?: return null
return connection.findByFQN(networkFqn)
}

override fun FirewallRule.endpointAddressGroup(endpointNumber: Int): AddressGroup? {
val addressGroupFqn = endpoint(endpointNumber)?.addressGroup ?: return null
return connection.findByFQN(addressGroupFqn)
}

override fun FirewallRule.serviceSrcPorts(): String? =
utils.formatPort(service.srcPorts)

override fun FirewallRule.serviceDstPorts(): String? =
utils.formatPort(service.dstPorts)

override fun FirewallRule.endpointTags(endpointNumber: Int): List<Tag?>? {
val rawTags = endpoint(endpointNumber)?.tags ?: return null
return rawTags.map {
tagFromString(qualifiedName, it)
}
}

private fun tagFromString(ruleFqn: List<String>, tagString: String): Tag? {
val projectFqn = ruleFqn.dropLast(1)
val isGlobal = tagString.split(":")[0] == "global"
val tagFqn = if (isGlobal) {
tagString.split(":")[1]
} else {
val fqnList = projectFqn + tagString
fqnList.joinToString(":")
}
return connection.findByFQN<Tag>(tagFqn)
}

private fun FirewallRuleEndpointType.type(): String? = when {
any == true -> EndpointType.AnyWorkload.value
addressGroup != null -> EndpointType.AddressGroup.value
virtualNetwork != null -> EndpointType.VirtualNetwork.value
tags.isNotEmpty() -> EndpointType.Tag.value
else -> EndpointType.None.value
}

private fun FirewallRule.endpoint(endpointNumber: Int): FirewallRuleEndpointType? = when (endpointNumber) {
1 -> endpoint1
2 -> endpoint2
else -> null
}
}
Expand Up @@ -6,22 +6,25 @@ 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.AllowedAddressPair
import net.juniper.contrail.api.types.FirewallRuleEndpointType
import net.juniper.contrail.api.types.FirewallServiceType
import net.juniper.contrail.api.types.IpamSubnetType
import net.juniper.contrail.api.types.NetworkIpam
import net.juniper.contrail.api.types.NetworkPolicy
import net.juniper.contrail.api.types.PolicyRuleType
import net.juniper.contrail.api.types.PortType
import net.juniper.contrail.api.types.RouteType
import net.juniper.contrail.api.types.SecurityGroup
import net.juniper.contrail.api.types.ServiceGroup
import net.juniper.contrail.api.types.SubnetType
import net.juniper.contrail.api.types.Tag
import net.juniper.contrail.api.types.VirtualNetwork
import net.juniper.contrail.api.types.VnSubnetsType
import net.juniper.contrail.api.types.AllowedAddressPair
import net.juniper.contrail.api.types.FirewallServiceType
import net.juniper.contrail.api.types.IpamSubnetType
import net.juniper.contrail.api.types.ServiceGroup
import net.juniper.contrail.vro.base.Description
import net.juniper.contrail.vro.config.constants.minPort
import net.juniper.contrail.vro.config.constants.EndpointType
import net.juniper.contrail.vro.config.constants.maxPort
import net.juniper.contrail.vro.config.constants.minPort
import net.juniper.contrail.vro.format.PropertyFormatter
import java.util.UUID

Expand Down Expand Up @@ -152,6 +155,9 @@ class Utils {
return ranges.map { parsePortRange(it, anyAsFullRange = true) }
}

fun parsePortsOfFirewallRule(ports: String): PortType =
parsePortRange(ports, true)

fun formatPort(port: PortType): String =
if (port.startPort == port.endPort)
if (port.startPort == -1) "any" else "${port.startPort}"
Expand Down Expand Up @@ -244,6 +250,22 @@ class Utils {
return AddressType(subnet, networkName, securityGroupName, policyName)
}

fun createEndpoint(
type: String,
tags: List<Tag>?,
virtualNetwork: VirtualNetwork?,
addressGroup: AddressGroup?
): FirewallRuleEndpointType {
val anyWorkload = type == EndpointType.AnyWorkload.value
val tagNames = if (type == EndpointType.Tag.value && tags != null) tags.map { tagToString(it) } else listOf()
val virtualNetworkFqn = virtualNetwork?.qualifiedName?.joinToString(":")
val addressGroupFqn = addressGroup?.qualifiedName?.joinToString(":")
return FirewallRuleEndpointType(null, virtualNetworkFqn, addressGroupFqn, tagNames, null, anyWorkload)
}

fun tagToString(tag: Tag): String =
if (tag.parentType == "project") tag.name else "global:${tag.name}"

fun randomUUID(): String =
UUID.randomUUID().toString()

Expand Down Expand Up @@ -284,9 +306,8 @@ class Utils {
"community-attributes ${route.communityAttributes?.communityAttribute?.joinToString(",") ?: ""}"
}

fun routeStringToIndex(routeString: String): Int {
return routeString.split(":")[0].toInt()
}
fun routeStringToIndex(routeString: String): Int =
routeString.split(":")[0].toInt()

fun subnetToString(subnet: SubnetType?): String? {
if (subnet == null) return null
Expand Down
Expand Up @@ -5,6 +5,7 @@
package net.juniper.contrail.vro.format

import net.juniper.contrail.api.ApiObjectBase
import net.juniper.contrail.api.types.FirewallRule
import net.juniper.contrail.api.types.FloatingIp
import net.juniper.contrail.api.types.IpamSubnetType
import net.juniper.contrail.api.types.QuotaType
Expand All @@ -29,4 +30,15 @@ object DisplayNameFormatter {

fun format(obj: QuotaType): String? =
"Quotas"

fun format(obj: FirewallRule): String? {
// `obj.parent?.name` returns null, so we use `obj.qualifiedName.dropLast(1).last()` to get the parent name.
val parentName = obj.qualifiedName.dropLast(1).last()
val simpleAction = obj.actionList?.simpleAction
val direction = obj.direction
val service = if (obj.service != null) PropertyFormatter.format(obj.service) else obj.serviceGroup[0].referredName.last()
val endpoint1 = PropertyFormatter.format(obj.endpoint1)
val endpoint2 = PropertyFormatter.format(obj.endpoint2)
return "$parentName: $simpleAction $service EP1: $endpoint1 $direction EP2: $endpoint2"
}
}
Expand Up @@ -49,6 +49,21 @@ object PropertyFormatter {
}
}

fun format(prop: FirewallRuleEndpointType): String = prop.run {
when {
subnet != null -> format(subnet)
virtualNetwork != null -> "VN:$virtualNetwork"
addressGroup != null -> "AG:$addressGroup"
any == true -> "ANY"
tags != null && tags.isNotEmpty() -> "Tags:${tags.joinToString(",")}"
else -> "-"
}
}

fun format(prop: FirewallServiceType): String = prop.run {
"$protocol:${format(srcPorts)}:${format(dstPorts)}"
}

fun format(prop: ShareType) =
"${prop.tenant}: ${prop.tenantAccess.formatAccess()}"

Expand All @@ -75,10 +90,6 @@ object PropertyFormatter {
"${actionList.safeSimpleAction}$protocol ${srcAddresses.inline} ${srcPorts.inline} $direction ${dstAddresses.inline} ${dstPorts.inline}"
}

fun format(prop: FirewallServiceType) = prop.run {
"$protocol:${format(srcPorts)}:${format(dstPorts)}"
}

private val ActionListType?.safeSimpleAction get() =
if (this == null) "" else "$simpleAction "

Expand Down
Expand Up @@ -7,6 +7,7 @@ import com.vmware.o11n.sdk.modeldriven.PluginContext
import com.vmware.o11n.sdk.modeldriven.Sid
import org.springframework.beans.factory.annotation.Autowired
import net.juniper.contrail.vro.base.ConnectionRepository
import net.juniper.contrail.vro.config.readUponQuery
import net.juniper.contrail.vro.model.Connection
import net.juniper.contrail.api.* // ktlint-disable no-wildcard-imports
import net.juniper.contrail.api.types.* // ktlint-disable no-wildcard-imports
Expand All @@ -17,6 +18,7 @@ private fun <T : ApiObjectBase> ConnectionRepository.query(clazz: Class<T>, quer
private fun <T : ApiObjectBase> Connection.query(clazz: Class<T>, query: String, key: String): List<FoundObject<T>>? =
list(clazz)?.asSequence()
?.filter { query.isBlank() || it.name.startsWith(query) }
?.onEach { if (readUponQuery.contains(clazz.simpleName)) read(it) }
?.map { FoundObject(it, info.sid.with(key, it.uuid)) }
?.toList()

Expand Down
Expand Up @@ -6,6 +6,7 @@ package net.juniper.contrail.vro.tests.workflows

import net.juniper.contrail.vro.gen.AddressGroup_Wrapper
import net.juniper.contrail.vro.gen.Connection_Wrapper
import net.juniper.contrail.vro.gen.FirewallRule_Wrapper
import net.juniper.contrail.vro.gen.FloatingIpPool_Wrapper
import net.juniper.contrail.vro.gen.FloatingIp_Wrapper
import net.juniper.contrail.vro.gen.IpamSubnetType_Wrapper
Expand Down Expand Up @@ -111,6 +112,13 @@ class Dependencies(private val connection: Connection_Wrapper, private val utils
setParentServiceInstance(parent)
}

@JvmOverloads
fun someFirewallRule(parent: Project_Wrapper = someProject()) = FirewallRule_Wrapper().apply {
uuid = randomStringUuid()
name = "someFirewallRule$uuid"
setParentProject(parent)
}

fun someServiceTemplate() = ServiceTemplate_Wrapper().apply {
uuid = randomStringUuid()
name = "someServiceTemplate$uuid"
Expand Down
@@ -0,0 +1,41 @@
var rule = new ContrailFirewallRule();
var ruleUuid = ContrailUtils.randomUUID();
rule.setUuid(ruleUuid);
rule.setName(ruleUuid);
if (typeof parentProject === 'undefined') {
// if the parent project is undefined, we're using the policy management version
var defaultPolicyManagement = parentConnection.findPolicyManagementByFQName("default-policy-management");
rule.setParentPolicyManagement(defaultPolicyManagement);
} else {
rule.setParentProject(parentProject);
}
rule.setDirection(direction);

var actions = new ContrailActionListType()
actions.setSimpleAction(action);
rule.setActionList(actions);

var endpoint1 = ContrailUtils.createEndpoint(endpoint1Type, endpoint1Tags, endpoint1VirtualNetwork, endpoint1AddressGroup);
var endpoint2 = ContrailUtils.createEndpoint(endpoint2Type, endpoint2Tags, endpoint2VirtualNetwork, endpoint2AddressGroup);
rule.setEndpoint1(endpoint1);
rule.setEndpoint2(endpoint2);

var mTags = new ContrailFirewallRuleMatchTagsType([]);
if(matchTags != null) {
mTags = new ContrailFirewallRuleMatchTagsType(matchTags);
}
rule.setMatchTags(mTags);

if(serviceType == "manual") {
var service = new ContrailFirewallServiceType();
service.setProtocol(serviceProtocol);
service.setSrcPorts(ContrailUtils.parsePortsOfFirewallRule(serviceSrcPorts));
service.setDstPorts(ContrailUtils.parsePortsOfFirewallRule(serviceDstPorts));
rule.setService(service);
} else {
if(serviceReference != null) {
rule.addServiceGroup(serviceReference);
}
}

rule.create();

0 comments on commit 9db7112

Please sign in to comment.