Skip to content

Commit

Permalink
Fix up a few things related to min, start and gateway address (#445)
Browse files Browse the repository at this point in the history
* Fix up a few things related to min, start and gateway address

- the get address pools api was incorrectly only returning the min address, not the configured gateway
- the IP allocation code was always starting at min address, instead of starting at start address
- min address should be the min address in the range, not the configured start address.
- Added a basic unit test for the ipam api
  • Loading branch information
william-richard committed Apr 28, 2016
1 parent 8c02e52 commit ecc62f3
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ case class GetPoolsAction(
"NETWORK" -> JsString(formatNetworkAddress(pool.network)),
"START_ADDRESS" -> JsString(pool.startAddress.getOrElse("Unspecified")),
"SPECIFIED_GATEWAY" -> JsString(pool.gateway.getOrElse("Unspecified")),
"GATEWAY" -> JsString(pool.ipCalc.minAddress),
"GATEWAY" -> JsString(pool.gateway.getOrElse(pool.ipCalc.minAddress)),
"BROADCAST" -> JsString(pool.ipCalc.broadcastAddress),
"POSSIBLE_ADDRESSES" -> JsNumber(pool.ipCalc.addressCount)
)
Expand Down
4 changes: 2 additions & 2 deletions app/collins/models/shared/IpAddressable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ trait IpAddressStorage[T <: IpAddressable] extends Schema with AnormAdapter[T] w
* For a range 0L..20L, used addresses List(17,18,19,20), the result will be None (allocate from beginning)
*/
protected def getCurrentLowestLocalMaxAddress(calc: IpAddressCalc)(implicit scope: Option[String]): Option[Long] = inTransaction {
val minAddress = calc.minAddressAsLong
val startAddress = calc.startAddressAsLong
val maxAddress = calc.maxAddressAsLong
val sortedAddresses = from(tableDef)(t =>
where(
(t.address gte minAddress) and
(t.address gte startAddress) and
(t.address lte maxAddress))
select (t.address)
orderBy (t.address asc)).toSeq
Expand Down
2 changes: 1 addition & 1 deletion app/collins/util/IpAddress.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ case class IpAddressCalc(network: String, startAt: Option[String] = None) {
def lastOctetInRange: Long = IpAddress.lastOctet(maxAddressAsLong)
def startAddress: String = startAt.getOrElse(minAddress)
def startAddressAsLong = IpAddress.toLong(startAddress)
def minAddress: String = startAt.getOrElse(subnetInfo.getLowAddress())
def minAddress: String = subnetInfo.getLowAddress()
def minAddressAsLong = IpAddress.toLong(minAddress)
def maxAddress: String = subnetInfo.getHighAddress()
def maxAddressAsLong = IpAddress.toLong(maxAddress)
Expand Down
45 changes: 45 additions & 0 deletions test/collins/controllers/IpamApiSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package collins.controllers

import collins._
import org.specs2._
import specification._
import play.api.test.WithApplication
import org.specs2.matcher.JsonMatchers

class IpamApiSpec extends mutable.Specification with ControllerSpec {

"IPAM API Specification".title

args(sequential = true)

"the REST API" should {
"Support getting pools" in new WithApplication with AssetApiHelper {
override val assetTag = "tumblrtag42"
val getRequest = FakeRequest("GET", "/api/address/pools")
val getResult = Extract.from(api.getAddressPools("true").apply(getRequest))
getResult must haveStatus(200)
getResult must haveJsonData.which { s =>
s must /("data") */("POOLS") */ ("NAME" -> "ADMIN-OPS")
s must /("data") */("POOLS") */ ("GATEWAY" -> "172.16.56.1")
s must /("data") */("POOLS") */ ("START_ADDRESS" -> "172.16.56.5")
s must /("data") */("POOLS") */ ("BROADCAST" -> "172.16.56.255")
s must /("data") */("POOLS") */ ("POSSIBLE_ADDRESSES" -> 254)
}
}
"Support creating an address starting with start address" in new WithApplication with AssetApiHelper {
override val assetTag = "tumblrtag42"
val pool = "ADMIN-OPS"
createAsset() must haveStatus(201)
val createRequest = FakeRequest("PUT", "/api/asset/%s/address?pool=%s".format(assetTag, pool))
val createResult = Extract.from(api.allocateAddress(assetTag).apply(createRequest))
createResult must haveStatus(201)
createResult must haveJsonData.which { s =>
s must /("data") */("ADDRESSES") */ ("ASSET_TAG" -> assetTag)
s must /("data") */("ADDRESSES") */ ("ADDRESS" -> "172.16.56.5")
s must /("data") */("ADDRESSES") */ ("GATEWAY" -> "172.16.56.1")
s must /("data") */("ADDRESSES") */ ("NETMASK" -> "255.255.255.0")
s must /("data") */("ADDRESSES") */ ("POOL" -> pool)
}
}
}
}

0 comments on commit ecc62f3

Please sign in to comment.