2
0
mirror of https://github.com/VinylDNS/vinyldns synced 2025-08-31 06:15:49 +00:00
This commit is contained in:
Jay07GIT
2023-08-22 23:58:33 +05:30
24 changed files with 282 additions and 187 deletions

View File

@@ -161,6 +161,17 @@ vinyldns {
port=${?API_SERVICE_PORT}
}
api {
limits {
batchchange-routing-max-items-limit = 100
membership-routing-default-max-items = 100
membership-routing-max-items-limit = 1000
membership-routing-max-groups-list-limit = 3000
recordset-routing-default-max-items= 100
zone-routing-default-max-items = 100
zone-routing-max-items-limit = 100
}
}
approved-name-servers = [
"172.17.42.1.",

View File

@@ -76,6 +76,18 @@ crypto {
secret = ${?CRYPTO_SECRET}
}
api {
limits {
batchchange-routing-max-items-limit = 100
membership-routing-default-max-items = 100
membership-routing-max-items-limit = 1000
membership-routing-max-groups-list-limit = 3000
recordset-routing-default-max-items= 100
zone-routing-default-max-items = 100
zone-routing-max-items-limit = 100
}
}
http.port = 9001
http.port = ${?PORTAL_PORT}

View File

@@ -164,6 +164,17 @@ vinyldns {
port=${?API_SERVICE_PORT}
}
api {
limits {
batchchange-routing-max-items-limit = 100
membership-routing-default-max-items = 100
membership-routing-max-items-limit = 1000
membership-routing-max-groups-list-limit = 3000
recordset-routing-default-max-items= 100
zone-routing-default-max-items = 100
zone-routing-max-items-limit = 100
}
}
approved-name-servers = [
"172.17.42.1.",

View File

@@ -611,12 +611,13 @@ class RecordSetService(
def listFailedRecordSetChanges(
authPrincipal: AuthPrincipal,
zoneId: Option[String] = None,
startFrom: Int= 0,
maxItems: Int = 100,
maxItems: Int = 100
): Result[ListFailedRecordSetChangesResponse] =
for {
recordSetChangesFailedResults <- recordChangeRepository
.listFailedRecordSetChanges(maxItems, startFrom)
.listFailedRecordSetChanges(zoneId, maxItems, startFrom)
.toResult[ListFailedRecordSetChangesResults]
_ <- zoneAccess(recordSetChangesFailedResults.items, authPrincipal).toResult
} yield

View File

@@ -120,6 +120,7 @@ trait RecordSetServiceAlgebra {
def listFailedRecordSetChanges(
authPrincipal: AuthPrincipal,
zoneId: Option[String],
startFrom: Int,
maxItems: Int
): Result[ListFailedRecordSetChangesResponse]

View File

@@ -269,7 +269,7 @@ class RecordSetRoute(
}
}
} ~
path("metrics" / "health" / "recordsetchangesfailure") {
path("metrics" / "health" / "zones" / Segment / "recordsetchangesfailure") {zoneId =>
(get & monitor("Endpoint.listFailedRecordSetChanges")) {
parameters("startFrom".as[Int].?(0), "maxItems".as[Int].?(DEFAULT_MAX_ITEMS)) {
(startFrom: Int, maxItems: Int) =>
@@ -279,7 +279,7 @@ class RecordSetRoute(
errorMsg = s"maxItems was $maxItems, maxItems must be between 0 exclusive " +
s"and $DEFAULT_MAX_ITEMS inclusive"
){
authenticateAndExecute(recordSetService.listFailedRecordSetChanges(_, startFrom, maxItems)) {
authenticateAndExecute(recordSetService.listFailedRecordSetChanges(_, Some(zoneId), startFrom, maxItems)) {
changes =>
complete(StatusCodes.OK, changes)
}

View File

@@ -2017,11 +2017,11 @@ class RecordSetServiceSpec
doReturn(IO.pure(ListFailedRecordSetChangesResults(completeRecordSetChanges)))
.when(mockRecordChangeRepo)
.listFailedRecordSetChanges(100,0)
.listFailedRecordSetChanges(Some(okZone.id),100,0)
val result: ListFailedRecordSetChangesResponse =
underTest.listFailedRecordSetChanges(authPrincipal = okAuth).value.unsafeRunSync().toOption.get
underTest.listFailedRecordSetChanges(authPrincipal = okAuth,Some(okZone.id)).value.unsafeRunSync().toOption.get
val changesWithName =
ListFailedRecordSetChangesResponse(
@@ -2042,11 +2042,11 @@ class RecordSetServiceSpec
doReturn(IO.pure(ListFailedRecordSetChangesResults(completeRecordSetChanges)))
.when(mockRecordChangeRepo)
.listFailedRecordSetChanges(3,2)
.listFailedRecordSetChanges(Some(okZone.id),3,2)
val result: ListFailedRecordSetChangesResponse =
underTest.listFailedRecordSetChanges(authPrincipal = okAuth,2,3).value.unsafeRunSync().toOption.get
underTest.listFailedRecordSetChanges(authPrincipal = okAuth,Some(okZone.id),2,3).value.unsafeRunSync().toOption.get
val changesWithName =
ListFailedRecordSetChangesResponse(

View File

@@ -421,9 +421,6 @@ class RecordSetRoutingSpec
private val failedChangesWithUserName =
List(rsChange1.copy(status = RecordSetChangeStatus.Failed) , rsChange2.copy(status = RecordSetChangeStatus.Failed))
private val listFailedRecordSetChangeResponse = ListFailedRecordSetChangesResponse(
failedChangesWithUserName,0,0,100
)
class TestService extends RecordSetServiceAlgebra {
@@ -585,14 +582,17 @@ class RecordSetRoutingSpec
def listFailedRecordSetChanges(
authPrincipal: AuthPrincipal,
zoneId:Option[String],
startFrom: Int,
maxItems: Int
): Result[ListFailedRecordSetChangesResponse] = {
val outcome = authPrincipal match {
case _ => Right(listFailedRecordSetChangeResponse)
}
outcome.toResult
}
zoneId match {
case Some(zoneNotFound.id) => Left(ZoneNotFoundError(s"$zoneId"))
case Some(notAuthorizedZone.id) => Left(NotAuthorizedError("no way"))
case _ => authPrincipal match {
case _ => Right(ListFailedRecordSetChangesResponse(failedChangesWithUserName,0,startFrom,maxItems))
}
}}.toResult
def searchRecordSets(
startFrom: Option[String],
@@ -942,7 +942,7 @@ class RecordSetRoutingSpec
val rsChangeFailed1 = rsChange1.copy(status = RecordSetChangeStatus.Failed)
val rsChangeFailed2 = rsChange2.copy(status = RecordSetChangeStatus.Failed)
Get(s"/metrics/health/recordsetchangesfailure") ~> recordSetRoute ~> check {
Get(s"/metrics/health/zones/${okZone.id}/recordsetchangesfailure") ~> recordSetRoute ~> check {
val changes = responseAs[ListFailedRecordSetChangesResponse]
changes.failedRecordSetChanges.map(_.id) shouldBe List(rsChangeFailed1.id, rsChangeFailed2.id)

View File

@@ -161,6 +161,18 @@ vinyldns {
port=${?API_SERVICE_PORT}
}
api {
limits {
batchchange-routing-max-items-limit = 100
membership-routing-default-max-items = 100
membership-routing-max-items-limit = 1000
membership-routing-max-groups-list-limit = 3000
recordset-routing-default-max-items= 100
zone-routing-default-max-items = 100
zone-routing-max-items-limit = 100
}
}
approved-name-servers = [
"172.17.42.1.",

View File

@@ -35,7 +35,8 @@ trait RecordChangeRepository extends Repository {
def getRecordSetChange(zoneId: String, changeId: String): IO[Option[RecordSetChange]]
def listFailedRecordSetChanges(maxItems: Int = 100,
def listFailedRecordSetChanges(zoneId: Option[String],
maxItems: Int = 100,
startFrom: Int = 0
): IO[ListFailedRecordSetChangesResults]

View File

@@ -183,19 +183,19 @@ class MySqlRecordChangeRepositoryIntegrationSpec
repo.save(db, ChangeSet(inserts))
}
saveRecChange.attempt.unsafeRunSync() shouldBe right
val result = repo.listFailedRecordSetChanges(10, 0).unsafeRunSync()
val result = repo.listFailedRecordSetChanges(Some(okZone.id),10, 0).unsafeRunSync()
(result.items should have).length(10)
result.maxItems shouldBe 10
result.items should contain theSameElementsAs(inserts)
}
"return empty for success record changes" in {
val inserts = generateInserts(okZone, 10)
val saveRecChange = executeWithinTransaction { db: DB =>
repo.save(db, ChangeSet(inserts))
}
saveRecChange.attempt.unsafeRunSync() shouldBe right
val result = repo.listFailedRecordSetChanges(5, 0).unsafeRunSync()
val result = repo.listFailedRecordSetChanges(Some(okZone.id),5, 0).unsafeRunSync()
(result.items should have).length(0)
result.items shouldBe List()
result.nextId shouldBe 0
@@ -215,17 +215,19 @@ class MySqlRecordChangeRepositoryIntegrationSpec
repo.save(db, ChangeSet(timeSpaced))
}
saveRecChange.attempt.unsafeRunSync() shouldBe right
val page1 = repo.listFailedRecordSetChanges(2, 0).unsafeRunSync()
page1.nextId shouldBe 2
val page1 = repo.listFailedRecordSetChanges(Some(okZone.id), 2, 0).unsafeRunSync()
println(page1.items)
page1.nextId shouldBe 3
page1.maxItems shouldBe 2
(page1.items should contain).theSameElementsInOrderAs(expectedOrder.take(2))
val page2 = repo.listFailedRecordSetChanges(2, page1.nextId).unsafeRunSync()
page2.nextId shouldBe 4
val page2 = repo.listFailedRecordSetChanges(Some(okZone.id), 2, page1.nextId).unsafeRunSync()
println(page2.items)
page2.nextId shouldBe 6
page2.maxItems shouldBe 2
(page2.items should contain).theSameElementsInOrderAs(expectedOrder.slice(2, 4))
(page2.items should contain).theSameElementsInOrderAs(expectedOrder.slice(3, 5))
val page3 = repo.listFailedRecordSetChanges(2, page2.nextId).unsafeRunSync()
val page3 = repo.listFailedRecordSetChanges(Some(okZone.id), 2, 4).unsafeRunSync()
page3.nextId shouldBe 0
page3.maxItems shouldBe 2
page3.items should contain theSameElementsAs expectedOrder.slice(4, 5)

View File

@@ -63,6 +63,7 @@ class MySqlRecordChangeRepository
sql"""
|SELECT data
| FROM record_change
| WHERE zone_id = {zoneId}
| ORDER BY created DESC
""".stripMargin
@@ -170,16 +171,17 @@ class MySqlRecordChangeRepository
}
}
def listFailedRecordSetChanges(maxItems: Int, startFrom: Int): IO[ListFailedRecordSetChangesResults] =
def listFailedRecordSetChanges(zoneId: Option[String], maxItems: Int, startFrom: Int): IO[ListFailedRecordSetChangesResults] =
monitor("repo.RecordChange.listFailedRecordSetChanges") {
IO {
DB.readOnly { implicit s =>
val queryResult = LIST_RECORD_CHANGES
.bindByName('zoneId -> zoneId.get)
.map(toRecordSetChange)
.list()
.apply()
val failedRecordSetChanges = queryResult.filter(rc => rc.status == RecordSetChangeStatus.Failed).drop(startFrom).take(maxItems)
val nextId = if (failedRecordSetChanges.size < maxItems) 0 else startFrom + maxItems
val nextId = if (failedRecordSetChanges.size < maxItems) 0 else startFrom + maxItems + 1
ListFailedRecordSetChangesResults(failedRecordSetChanges,nextId,startFrom,maxItems)
}
}

View File

@@ -24,7 +24,8 @@ case class Meta(
defaultTtl: Long,
manualBatchChangeReviewEnabled: Boolean,
scheduledBatchChangesEnabled: Boolean,
portalUrl: String
portalUrl: String,
maxGroupItemsDisplay: Int
)
object Meta {
def apply(config: Configuration): Meta =
@@ -35,6 +36,7 @@ object Meta {
config.getOptional[Long]("default-ttl").getOrElse(7200L),
config.getOptional[Boolean]("manual-batch-review-enabled").getOrElse(false),
config.getOptional[Boolean]("scheduled-changes-enabled").getOrElse(false),
config.getOptional[String]("portal.vinyldns.url").getOrElse("http://localhost:9001")
config.getOptional[String]("portal.vinyldns.url").getOrElse("http://localhost:9001"),
config.getOptional[Int]("api.limits.membership-routing-max-groups-list-limit").getOrElse(3000)
)
}

View File

@@ -3,7 +3,7 @@
@content = {
<!-- PAGE CONTENT -->
<div class="right_col" role="main" ng-init="batchChangeLimit = @meta.batchChangeLimit; defaultTtl = @meta.defaultTtl;
manualReviewEnabled = @meta.manualBatchChangeReviewEnabled">
manualReviewEnabled = @meta.manualBatchChangeReviewEnabled; maxGroupItemsDisplay = @meta.maxGroupItemsDisplay">
<!-- BREADCRUMB -->
<ul class="breadcrumb">
@@ -336,7 +336,8 @@
<button type="button" id="create-batch-changes-button" class="btn btn-primary" ng-click="submitChange(manualReviewEnabled)">Submit</button>
</div>
<div ng-if="formStatus=='pendingConfirm'" class="pull-right">
<span>{{ confirmationPrompt }}</span>
<span ng-if="!batchChangeErrors">{{ confirmationPrompt }}</span>
<span ng-if="batchChangeErrors" class="batch-change-error-help">There were errors, please review the highlighted rows and then proceed.</span>
<button class="btn btn-default" ng-click="cancelSubmit()">Cancel</button>
<button class="btn btn-success" type="submit" ng-click="confirmSubmit(createBatchChangeForm)">Confirm</button>
</div>

View File

@@ -70,53 +70,56 @@
</div>
</div>
<!-- START RECORD TABLE -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Records {{ getRecordPageTitle() }}</h3>
</div>
<div class="panel-body">
<div class="vinyldns-panel-top">
<div class="btn-group">
<button id="refresh-records-button" class="btn btn-default" ng-click="refreshRecords()"><span class="fa fa-refresh"></span> Refresh</button>
<button id="create-record-button" class="btn btn-default" ng-if="canCreateRecords" ng-click="createRecord(defaultTtl)"><span class="fa fa-plus"></span> Create Record Set</button>
</div>
<div>
<form class="input-group" ng-submit="refreshRecords()">
<div class="input-group">
<span class="input-group-btn">
<button id="record-search-button" type="submit" class="btn btn-primary"><span class="fa fa-search"></span></button>
</span>
<input id="record-search-text" ng-model="query" type="text" class="form-control" placeholder="Record Name">
<!-- START RECORD TABLE -->
<div class="panel panel-default">
<div class="panel-heading">
<div class="row">
<div class="col-md-10">
<span class="panel-title bolder-font-weight">Records</span>
</div>
<div class="col-md-2 pull-right">
<form class="input-group remove-bottom-margin" ng-submit="refreshRecords()">
<div class="input-group remove-bottom-margin">
<span class="input-group-btn">
<button id="record-search-button" type="submit" class="btn btn-primary"><span class="fa fa-search"></span></button>
</span>
<input id="record-search-text" ng-model="query" type="text" class="form-control" placeholder="Record Name">
</div>
</form>
<div class="dropdown">
<a class="record-type-filter-heading force-cursor dropdown-toggle" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">Filters<i class="fa fa-chevron-down"></i></a>
<div class="dropdown-menu" aria-labelledby="dropdownMenu1">
Record Types
<div>
<ul class="record-type-filters">
<li ng-repeat="recordType in readRecordTypes" style="list-style-type:none;"><input type="checkbox" ng-checked="selectedRecordTypes.indexOf(recordType) != -1" ng-click="toggleCheckedRecordType(recordType)"> {{recordType}}</li>
</ul>
</div>
<div class="dropdown">
<a class="record-type-filter-heading force-cursor dropdown-toggle" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">Filters<i class="fa fa-chevron-down"></i></a>
<div class="dropdown-menu" aria-labelledby="dropdownMenu1">
Record Types
<div>
<ul class="record-type-filters">
<li ng-repeat="recordType in readRecordTypes" style="list-style-type:none;"><input type="checkbox" ng-checked="selectedRecordTypes.indexOf(recordType) != -1" ng-click="toggleCheckedRecordType(recordType)"> {{recordType}}</li>
</ul>
</div>
<div>
Record Owner Group
<div>
<select class="form-control" id="recordOwnerGroup" ng-model="ownerGroupFilter" ng-options="group.id as group.name for group in groups | orderBy: 'name'" ng-click="$event.stopPropagation();">
<option value=""></option>
</select>
</div>
</div>
<div>
Record Owner Group
<div>
<select class="form-control" id="recordOwnerGroup" ng-model="ownerGroupFilter" ng-options="group.id as group.name for group in groups | orderBy: 'name'" ng-click="$event.stopPropagation();">
<option value=""></option>
</select>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="panel-body">
<div class="vinyldns-panel-top">
<div class="btn-group">
<button id="refresh-records-button" class="btn btn-default" ng-click="refreshRecords()"><span class="fa fa-refresh"></span> Refresh</button>
<button id="create-record-button" class="btn btn-default" ng-if="canCreateRecords" ng-click="createRecord(defaultTtl)"><span class="fa fa-plus"></span> Create Record Set</button>
</div>
</div>
<!-- PAGINATION -->
<div class="dataTables_paginate">
<div class="dataTables_paginate vinyldns_paginate">
<span class="vinyldns_page_number">{{ getRecordPageTitle() }}</span>
<ul class="pagination">
<li class="paginate_button previous">
<a ng-if="prevPageEnabled()" ng-click="prevPage()">Previous</a>
@@ -383,7 +386,8 @@
<!-- PAGINATION -->
<div class="dataTables_paginate">
<div class="dataTables_paginate vinyldns_paginate">
<span class="vinyldns_page_number">{{ getRecordPageTitle() }}</span>
<ul class="pagination">
<li class="paginate_button previous">
<a ng-if="prevPageEnabled()" ng-click="prevPage()">Previous</a>

View File

@@ -59,37 +59,41 @@
<!-- START RECORD TABLE -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Records {{ getRecordPageTitle() }}</h3>
</div>
<div class="panel-body">
<div class="vinyldns-panel-top">
<div class="btn-group">
<button id="refresh-records-button" class="btn btn-default" ng-click="refreshRecords()"><span class="fa fa-refresh"></span> Refresh</button>
<button id="create-record-button" class="btn btn-default" ng-if="canReadZone && (zoneInfo.accessLevel == 'Delete' || canCreateRecordsViaAcl())" ng-click="createRecord(defaultTtl)"><span class="fa fa-plus"></span> Create Record Set</button>
<button id="zone-sync-button" class="btn btn-default mb-control" ng-if="zoneInfo.accessLevel=='Delete'" data-toggle="modal" data-target="#mb-sync"><span class="fa fa-exchange"></span> Sync Zone</button>
</div>
<div>
<form class="input-group" ng-submit="refreshRecords()">
<div class="input-group">
<span class="input-group-btn">
<button id="record-search-button" type="submit" class="btn btn-primary"><span class="fa fa-search"></span></button>
</span>
<input id="record-search-text" ng-model="query" type="text" class="form-control" placeholder="Record Name">
</div>
<div class="row">
<div class="col-md-10">
<span class="panel-title bolder-font-weight">Records</span>
</div>
<div class="col-md-2 pull-right">
<form class="input-group remove-bottom-margin" ng-submit="refreshRecords()">
<div class="input-group remove-bottom-margin">
<span class="input-group-btn">
<button id="record-search-button" type="submit" class="btn btn-primary"><span class="fa fa-search"></span></button>
</span>
<input id="record-search-text" ng-model="query" type="text" class="form-control" placeholder="Record Name">
</div>
</form>
<div class="dropdown">
<a class="record-type-filter-heading force-cursor dropdown-toggle" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">Filter By Record Type <i class="fa fa-chevron-down"></i></a>
<ul class="dropdown-menu record-type-filters" aria-labelledby="dropdownMenu1">
<li ng-repeat="recordType in readRecordTypes"><input type="checkbox" ng-checked="selectedRecordTypes.indexOf(recordType) != -1" ng-click="toggleCheckedRecordType(recordType)"> {{recordType}}</li>
</ul>
</div>
</form>
</div>
</div>
</div>
<div class="panel-body">
<div class="vinyldns-panel-top">
<div class="btn-group">
<button id="refresh-records-button" class="btn btn-default" ng-click="refreshRecords()"><span class="fa fa-refresh"></span> Refresh</button>
<button id="create-record-button" class="btn btn-default" ng-if="canReadZone && (zoneInfo.accessLevel == 'Delete' || canCreateRecordsViaAcl())" ng-click="createRecord(defaultTtl)"><span class="fa fa-plus"></span> Create Record Set</button>
<button id="zone-sync-button" class="btn btn-default mb-control" ng-if="zoneInfo.accessLevel=='Delete'" data-toggle="modal" data-target="#mb-sync"><span class="fa fa-exchange"></span> Sync Zone</button>
</div>
</div>
</div>
<!-- PAGINATION -->
<div class="dataTables_paginate">
<div class="dataTables_paginate vinyldns_paginate">
<span class="vinyldns_page_number">{{ getRecordPageTitle() }}</span>
<ul class="pagination">
<li class="paginate_button previous">
<a ng-if="prevPageEnabled()" ng-click="prevPage()">Previous</a>
@@ -345,18 +349,19 @@
</tbody>
</table>
<!-- PAGINATION -->
<div class="dataTables_paginate">
<ul class="pagination">
<li class="paginate_button previous">
<a ng-if="prevPageEnabled()" ng-click="prevPage()">Previous</a>
</li>
<li class="paginate_button next">
<a ng-if="nextPageEnabled()" ng-click="nextPage()">Next</a>
</li>
</ul>
</div>
<!-- END PAGINATION -->
<!-- PAGINATION -->
<div class="dataTables_paginate vinyldns_paginate">
<span class="vinyldns_page_number">{{ getRecordPageTitle() }}</span>
<ul class="pagination">
<li class="paginate_button previous">
<a ng-if="prevPageEnabled()" ng-click="prevPage()">Previous</a>
</li>
<li class="paginate_button next">
<a ng-if="nextPageEnabled()" ng-click="nextPage()">Next</a>
</li>
</ul>
</div>
<!-- END PAGINATION -->
</div>
<div class="panel-footer"></div>

View File

@@ -13,7 +13,7 @@
</h3>
<!-- START ZONE INFO FORM -->
<div>
<div ng-init="maxGroupItemsDisplay = @meta.maxGroupItemsDisplay">
<form class="form-horizontal">
<div class="panel panel-default">
<div class="panel-heading">

View File

@@ -40,48 +40,42 @@
<!-- SIMPLE DATATABLE -->
<div class="panel panel-default">
<div class="panel-heading">
<div class="btn-group">
<button class="btn btn-default" ng-click="resetCurrentZone()" data-toggle="modal"
data-target="#zone_connection_modal" id="open-zone-modal-button">
<span class="fa fa-arrow-right"></span> Connect
</button>
<button id="zone-refresh-button" class="btn btn-default" ng-click="refreshZones()">
<span class="fa fa-refresh"></span> Refresh
</button>
</div>
<!-- SEARCH BOX -->
<div class="pull-right">
<form class="input-group" ng-submit="refreshZones()">
<div class="input-group">
<span class="input-group-btn">
<button id="zone-search-button" type="submit" class="btn btn-primary btn-left-round">
<span class="fa fa-search"></span>
</button>
</span>
<input ng-model="query" type="text" class="form-control zone-search-text" placeholder="{{!searchByAdminGroup ? 'Zone Name' : 'Admin Group Name'}}"/>
</div>
<div class="checkbox pull-right">
<label>
<div class="row flex">
<div class="btn-group col-md-9 flex-1">
<button class="btn btn-default" ng-click="resetCurrentZone()" data-toggle="modal" data-target="#zone_connection_modal" id="open-zone-modal-button">
<span class="fa fa-arrow-right"></span> Connect
</button>
<button id="zone-refresh-button" class="btn btn-default" ng-click="refreshZones()">
<span class="fa fa-refresh"></span> Refresh
</button>
</div>
<div class="col-md-3 pull-right">
<!-- SEARCH BOX -->
<form class="input-group remove-bottom-margin full-width" ng-submit="refreshZones()">
<div class="input-group remove-bottom-margin">
<span class="input-group-btn">
<button id="zone-search-button" type="submit" class="btn btn-primary btn-left-round">
<span class="fa fa-search"></span>
</button>
</span>
<input ng-model="query" type="text" class="form-control zone-search-text" placeholder="{{!searchByAdminGroup ? 'Zone Name' : 'Admin Group Name'}}"/>
</div>
</form>
<!-- END SEARCH BOX -->
<div class="flex">
<label class="reduce-font-weight remove-bottom-margin flex-1">
<input class="isGroupSearch" type="checkbox" ng-model="searchByAdminGroup" ng-change="refreshZones()"> Search by admin group
</label>
</div>
<div class="pull-right">
<div class="input-group" style="padding-right: 10px;">
<div class="ptr-zone-filter">
<form action="">
<div class="checkbox pull-right">
<label>
<input type="checkbox" ng-model="includeReverse" ng-true-value="false" ng-false-value="true" ng-change="refreshZones()"> Hide PTR Zones
</label>
</div>
</form>
<form action="" class="pull-right flex-1">
<div>
<label class="reduce-font-weight remove-bottom-margin">
<input type="checkbox" ng-model="includeReverse" ng-true-value="false" ng-false-value="true" ng-change="refreshZones()"> Hide PTR Zones
</label>
</div>
</div>
</form>
</div>
</form>
</div>
</div>
<!-- END SEARCH BOX -->
</div>
<div id="zone-list-table" class="panel-body">
<p ng-if="!zonesLoaded">Loading zones...</p>
@@ -171,44 +165,39 @@
<!-- SIMPLE DATATABLE -->
<div class="panel panel-default">
<div class="panel-heading">
<button id="zone-refresh-button" class="btn btn-default" ng-click="refreshZones()">
<span class="fa fa-refresh"></span> Refresh
</button>
<!-- SEARCH BOX -->
<div class="pull-right">
<form class="input-group" ng-submit="refreshZones()">
<div class="input-group">
<span class="input-group-btn">
<button id="all-zones-search-button" type="submit" class="btn btn-primary btn-left-round">
<span class="fa fa-search"></span>
</button>
</span>
<input ng-model="query" type="text" class="form-control zone-search-text" placeholder="{{!searchByAdminGroup ? 'Zone Name' : 'Admin Group Name'}}"/>
</div>
<div class="checkbox pull-right">
<label>
<div class="row flex">
<div class="btn-group col-md-9 flex-1">
<button id="zone-refresh-button" class="btn btn-default" ng-click="refreshZones()">
<span class="fa fa-refresh"></span> Refresh
</button>
</div>
<div class="col-md-3 pull-right">
<!-- SEARCH BOX -->
<form class="input-group remove-bottom-margin full-width" ng-submit="refreshZones()">
<div class="input-group remove-bottom-margin">
<span class="input-group-btn">
<button id="all-zones-search-button" type="submit" class="btn btn-primary btn-left-round">
<span class="fa fa-search"></span>
</button>
</span>
<input ng-model="query" type="text" class="form-control zone-search-text" placeholder="{{!searchByAdminGroup ? 'Zone Name' : 'Admin Group Name'}}"/>
</div>
</form>
<!-- END SEARCH BOX -->
<div class="flex">
<label class="reduce-font-weight remove-bottom-margin flex-1">
<input class="isGroupSearch" type="checkbox" ng-model="searchByAdminGroup" ng-change="refreshZones()"> Search by admin group
</label>
</div>
<div class="pull-right">
<div class="input-group" style="padding-right: 10px;">
<div class="ptr-zone-filter">
<form action="">
<div class="checkbox pull-right">
<label>
<input type="checkbox" ng-model="includeReverse" ng-true-value="false" ng-false-value="true" ng-change="refreshZones()"> Hide PTR Zones
</label>
</div>
</form>
<form action="" class="pull-right flex-1">
<div>
<label class="reduce-font-weight remove-bottom-margin">
<input type="checkbox" ng-model="includeReverse" ng-true-value="false" ng-false-value="true" ng-change="refreshZones()"> Hide PTR Zones
</label>
</div>
</div>
</form>
</div>
</form>
</div>
</div>
<!-- END SEARCH BOX -->
</div>
<div id="zone-list-table" class="panel-body">
<p ng-if="!allZonesLoaded">Loading zones...</p>

View File

@@ -76,6 +76,18 @@ crypto {
secret = ${?CRYPTO_SECRET}
}
api {
limits {
batchchange-routing-max-items-limit = 100
membership-routing-default-max-items = 100
membership-routing-max-items-limit = 1000
membership-routing-max-groups-list-limit = 3000
recordset-routing-default-max-items= 100
zone-routing-default-max-items = 100
zone-routing-max-items-limit = 100
}
}
http.port = 9001
http.port = ${?PORTAL_PORT}

View File

@@ -458,10 +458,6 @@ input[type="file"] {
align-items: center;
}
.paginate_left {
float: left;
}
.vinyldns_page_number {
margin-right: 10px;
}
@@ -570,3 +566,27 @@ input[type="file"] {
#set-dropdown-width {
width: 4em;
}
.full-width {
width: 100%;
}
.remove-bottom-margin {
margin-bottom: 0px;
}
.reduce-font-weight {
font-weight: 400;
}
.bolder-font-weight{
font-weight: 500;
}
.flex {
display: flex;
}
.flex-1{
flex: 1;
}

View File

@@ -29,6 +29,7 @@ angular.module('controller.groups', []).controller('GroupsController', function
$scope.hasGroups = false;
$scope.query = "";
$scope.validEmailDomains= [];
$scope.maxGroupItemsDisplay = 3000;
// Paging status for group sets
var groupsPaging = pagingService.getNewPagingParams(100);
@@ -203,7 +204,7 @@ angular.module('controller.groups', []).controller('GroupsController', function
}
return groupsService
.getGroups($scope.ignoreAccess, $scope.query)
.getGroups($scope.ignoreAccess, $scope.query, $scope.maxGroupItemsDisplay)
.then(success)
.catch(function (error) {
handleError(error, 'groupsService::getGroups-failure');

View File

@@ -85,7 +85,7 @@
$.ajax({
url: "/api/recordsets?maxItems=100",
dataType: "json",
data: "recordNameFilter="+request.term+"%25&nameSort=asc",
data: {recordNameFilter: request.term, nameSort: $scope.nameSort},
success: function( data ) {
const recordSearch = JSON.parse(JSON.stringify(data));
response($.map(recordSearch.recordSets, function(item) {

View File

@@ -74,12 +74,12 @@ angular.module('service.groups', [])
return $http.delete(url, {headers: utilityService.getCsrfHeader()});
};
this.getGroups = function (ignoreAccess, query) {
this.getGroups = function (ignoreAccess, query, maxItems) {
if (query == "") {
query = null;
}
var params = {
"maxItems": 3000,
"maxItems": maxItems,
"groupNameFilter": query,
"ignoreAccess": ignoreAccess
};

View File

@@ -65,5 +65,13 @@ class MetaSpec extends Specification with Mockito {
val config = Map("scheduled-changes-enabled" -> true)
Meta(Configuration.from(config)).scheduledBatchChangesEnabled must beTrue
}
"default to 3000 if membership-routing-max-groups-list-limit is not found" in {
val config = Map("vinyldns.version" -> "foo-bar")
Meta(Configuration.from(config)).maxGroupItemsDisplay must beEqualTo(3000)
}
"get the membership-routing-max-groups-list-limit value in config" in {
val config = Map("api.limits.membership-routing-max-groups-list-limit" -> 3100)
Meta(Configuration.from(config)).maxGroupItemsDisplay must beEqualTo(3100)
}
}
}