mirror of
https://github.com/VinylDNS/vinyldns
synced 2025-08-22 02:02:14 +00:00
Merge branch 'master' into aravindhr/optimize-batch-change
This commit is contained in:
commit
e54dc71fe0
@ -21,6 +21,7 @@ in any way, but do not see your name here, please open a PR to add yourself (in
|
||||
- Joe Crowe
|
||||
- Jearvon Dharrie
|
||||
- Andrew Dunn
|
||||
- Josh Edwards
|
||||
- Ryan Emerle
|
||||
- David Grizzanti
|
||||
- Alejandro Guirao
|
||||
@ -41,8 +42,9 @@ in any way, but do not see your name here, please open a PR to add yourself (in
|
||||
- Khalid Reid
|
||||
- Timo Schmid
|
||||
- Trent Schmidt
|
||||
- Nick Spadaccino
|
||||
- Arpit Shah
|
||||
- Ghafar Shah
|
||||
- Nick Spadaccino
|
||||
- Rebecca Star
|
||||
- Jess Stodola
|
||||
- Juan Valencia
|
||||
|
@ -146,7 +146,8 @@ See the [Contributing Guide](CONTRIBUTING.md).
|
||||
The current maintainers (people who can merge pull requests) are:
|
||||
|
||||
- Ryan Emerle ([@remerle](https://github.com/remerle))
|
||||
- Sriram Ramakrishnan ([@sramakr](https://github.com/sramakr))
|
||||
- Arpit Shah ([@arpit4ever](https://github.com/arpit4ever))
|
||||
- Nick Spadaccino ([@nspadaccino](https://github.com/nspadaccino))
|
||||
- Jim Wakemen ([@jwakemen](https://github.com/jwakemen))
|
||||
|
||||
See [AUTHORS.md](AUTHORS.md) for the full list of contributors to VinylDNS.
|
||||
|
@ -584,21 +584,19 @@ class RecordSetService(
|
||||
} yield change
|
||||
|
||||
def listRecordSetChanges(
|
||||
zoneId: Option[String] = None,
|
||||
zoneId: String,
|
||||
startFrom: Option[Int] = None,
|
||||
maxItems: Int = 100,
|
||||
fqdn: Option[String] = None,
|
||||
recordType: Option[RecordType] = None,
|
||||
authPrincipal: AuthPrincipal
|
||||
): Result[ListRecordSetChangesResponse] =
|
||||
for {
|
||||
zone <- getZone(zoneId.get)
|
||||
zone <- getZone(zoneId)
|
||||
_ <- canSeeZone(authPrincipal, zone).toResult
|
||||
recordSetChangesResults <- recordChangeRepository
|
||||
.listRecordSetChanges(Some(zone.id), startFrom, maxItems, fqdn, recordType)
|
||||
.listRecordSetChanges(Some(zone.id), startFrom, maxItems, None, None)
|
||||
.toResult[ListRecordSetChangesResults]
|
||||
recordSetChangesInfo <- buildRecordSetChangeInfo(recordSetChangesResults.items)
|
||||
} yield ListRecordSetChangesResponse(zoneId.get, recordSetChangesResults, recordSetChangesInfo)
|
||||
} yield ListRecordSetChangesResponse(zoneId, recordSetChangesResults, recordSetChangesInfo)
|
||||
|
||||
def listRecordSetChangeHistory(
|
||||
zoneId: Option[String] = None,
|
||||
|
@ -101,11 +101,9 @@ trait RecordSetServiceAlgebra {
|
||||
): Result[RecordSetChange]
|
||||
|
||||
def listRecordSetChanges(
|
||||
zoneId: Option[String],
|
||||
zoneId: String,
|
||||
startFrom: Option[Int],
|
||||
maxItems: Int,
|
||||
fqdn: Option[String],
|
||||
recordType: Option[RecordType],
|
||||
authPrincipal: AuthPrincipal
|
||||
): Result[ListRecordSetChangesResponse]
|
||||
|
||||
|
@ -230,8 +230,8 @@ class RecordSetRoute(
|
||||
} ~
|
||||
path("zones" / Segment / "recordsetchanges") { zoneId =>
|
||||
(get & monitor("Endpoint.listRecordSetChanges")) {
|
||||
parameters("startFrom".as[Int].?, "maxItems".as[Int].?(DEFAULT_MAX_ITEMS), "fqdn".as[String].?, "recordType".as[String].?) {
|
||||
(startFrom: Option[Int], maxItems: Int, fqdn: Option[String], _: Option[String]) =>
|
||||
parameters("startFrom".as[Int].?, "maxItems".as[Int].?(DEFAULT_MAX_ITEMS)) {
|
||||
(startFrom: Option[Int], maxItems: Int) =>
|
||||
handleRejections(invalidQueryHandler) {
|
||||
validate(
|
||||
check = 0 < maxItems && maxItems <= DEFAULT_MAX_ITEMS,
|
||||
@ -240,7 +240,7 @@ class RecordSetRoute(
|
||||
) {
|
||||
authenticateAndExecute(
|
||||
recordSetService
|
||||
.listRecordSetChanges(Some(zoneId), startFrom, maxItems, fqdn, None, _)
|
||||
.listRecordSetChanges(zoneId, startFrom, maxItems, _)
|
||||
) { changes =>
|
||||
complete(StatusCodes.OK, changes)
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ pyhamcrest==2.0.2
|
||||
pytz>=2014
|
||||
pytest==6.2.5
|
||||
mock==4.0.3
|
||||
dnspython==2.1.0
|
||||
dnspython==2.6.1
|
||||
boto3==1.18.51
|
||||
botocore==1.21.51
|
||||
requests==2.31.0
|
||||
requests==2.32.3
|
||||
pytest-xdist==2.4.0
|
||||
python-dateutil==2.8.2
|
||||
filelock==3.2.0
|
||||
pytest-custom_exit_code==0.3.0
|
||||
pytest-custom_exit_code==0.3.0
|
||||
|
@ -1937,19 +1937,22 @@ class RecordSetServiceSpec
|
||||
val completeRecordSetChanges: List[RecordSetChange] =
|
||||
List(pendingCreateAAAA, pendingCreateCNAME, completeCreateAAAA, completeCreateCNAME)
|
||||
|
||||
doReturn(IO.pure(Some(zoneActive)))
|
||||
.when(mockZoneRepo)
|
||||
.getZone(zoneActive.id)
|
||||
doReturn(IO.pure(ListRecordSetChangesResults(completeRecordSetChanges)))
|
||||
.when(mockRecordChangeRepo)
|
||||
.listRecordSetChanges(zoneId = Some(okZone.id), startFrom = None, maxItems = 100, fqdn = None, recordType = None)
|
||||
.listRecordSetChanges(zoneId = Some(zoneActive.id), startFrom = None, maxItems = 100, fqdn = None, recordType = None)
|
||||
doReturn(IO.pure(ListUsersResults(Seq(okUser), None)))
|
||||
.when(mockUserRepo)
|
||||
.getUsers(any[Set[String]], any[Option[String]], any[Option[Int]])
|
||||
|
||||
val result: ListRecordSetChangesResponse =
|
||||
underTest.listRecordSetChanges(Some(okZone.id), authPrincipal = okAuth).value.unsafeRunSync().toOption.get
|
||||
underTest.listRecordSetChanges(zoneActive.id, authPrincipal = okAuth).value.unsafeRunSync().toOption.get
|
||||
val changesWithName =
|
||||
completeRecordSetChanges.map(change => RecordSetChangeInfo(change, Some("ok")))
|
||||
val expectedResults = ListRecordSetChangesResponse(
|
||||
zoneId = okZone.id,
|
||||
zoneId = zoneActive.id,
|
||||
recordSetChanges = changesWithName,
|
||||
nextId = None,
|
||||
startFrom = None,
|
||||
@ -1996,7 +1999,7 @@ class RecordSetServiceSpec
|
||||
.getUsers(any[Set[String]], any[Option[String]], any[Option[Int]])
|
||||
|
||||
val result: ListRecordSetChangesResponse =
|
||||
underTest.listRecordSetChanges(Some(okZone.id), authPrincipal = okAuth).value.unsafeRunSync().toOption.get
|
||||
underTest.listRecordSetChanges(okZone.id, authPrincipal = okAuth).value.unsafeRunSync().toOption.get
|
||||
val expectedResults = ListRecordSetChangesResponse(
|
||||
zoneId = okZone.id,
|
||||
recordSetChanges = List(),
|
||||
@ -2062,7 +2065,7 @@ class RecordSetServiceSpec
|
||||
|
||||
"return a NotAuthorizedError" in {
|
||||
val error =
|
||||
underTest.listRecordSetChanges(Some(zoneNotAuthorized.id), authPrincipal = okAuth).value.unsafeRunSync().swap.toOption.get
|
||||
underTest.listRecordSetChanges(zoneNotAuthorized.id, authPrincipal = okAuth).value.unsafeRunSync().swap.toOption.get
|
||||
|
||||
error shouldBe a[NotAuthorizedError]
|
||||
}
|
||||
@ -2079,7 +2082,7 @@ class RecordSetServiceSpec
|
||||
.getUsers(any[Set[String]], any[Option[String]], any[Option[Int]])
|
||||
|
||||
val result: ListRecordSetChangesResponse =
|
||||
underTest.listRecordSetChanges(Some(okZone.id), authPrincipal = okAuth).value.unsafeRunSync().toOption.get
|
||||
underTest.listRecordSetChanges(okZone.id, authPrincipal = okAuth).value.unsafeRunSync().toOption.get
|
||||
val changesWithName =
|
||||
List(RecordSetChangeInfo(rsChange2, Some("ok")), RecordSetChangeInfo(rsChange1, Some("ok")))
|
||||
val expectedResults = ListRecordSetChangesResponse(
|
||||
|
@ -758,16 +758,14 @@ class RecordSetRoutingSpec
|
||||
}.toResult
|
||||
|
||||
def listRecordSetChanges(
|
||||
zoneId: Option[String],
|
||||
zoneId: String,
|
||||
startFrom: Option[Int],
|
||||
maxItems: Int,
|
||||
fqdn: Option[String],
|
||||
recordType: Option[RecordType],
|
||||
authPrincipal: AuthPrincipal
|
||||
): Result[ListRecordSetChangesResponse] = {
|
||||
zoneId match {
|
||||
case Some(zoneNotFound.id) => Left(ZoneNotFoundError(s"$zoneId"))
|
||||
case Some(notAuthorizedZone.id) => Left(NotAuthorizedError("no way"))
|
||||
case zoneNotFound.id => Left(ZoneNotFoundError(s"$zoneId"))
|
||||
case notAuthorizedZone.id => Left(NotAuthorizedError("no way"))
|
||||
case _ => Right(listRecordSetChangesResponse)
|
||||
}
|
||||
}.toResult
|
||||
|
@ -17,7 +17,7 @@ can read data from the Directory. Once you have that information, proceed to th
|
||||
**Considerations**
|
||||
You _should_ communicate to your Directory over LDAP using TLS. To do so, the SSL certs should be installed
|
||||
on the portal servers, or provided via a java trust store (key store). The portal provides an option to specific
|
||||
a java key store when it starts up.
|
||||
a java key store when it starts up. For more information: [Using Java Key Store In VinylDNS](https://github.com/vinyldns/vinyldns/tree/master/modules/portal#building-locally)
|
||||
|
||||
## Configuring LDAP
|
||||
Before you can configure LDAP, make note of the host, username, and password that you will be using.
|
||||
|
@ -23,7 +23,7 @@ import vinyldns.core.domain.record.RecordType.RecordType
|
||||
import vinyldns.core.domain.record._
|
||||
import vinyldns.core.protobuf.ProtobufConversions
|
||||
import vinyldns.core.route.Monitored
|
||||
import vinyldns.mysql.repository.MySqlRecordSetRepository.fromRecordType
|
||||
import vinyldns.mysql.repository.MySqlRecordSetRepository.{fromRecordType, toFQDN}
|
||||
import vinyldns.proto.VinylDNSProto
|
||||
|
||||
class MySqlRecordChangeRepository
|
||||
@ -103,7 +103,7 @@ class MySqlRecordChangeRepository
|
||||
change.zoneId,
|
||||
change.created.toEpochMilli,
|
||||
fromChangeType(change.changeType),
|
||||
if(change.recordSet.name == change.zone.name) change.zone.name else change.recordSet.name + "." + change.zone.name,
|
||||
toFQDN(change.zone.name, change.recordSet.name),
|
||||
fromRecordType(change.recordSet.typ),
|
||||
toPB(change).toByteArray,
|
||||
)
|
||||
|
@ -347,7 +347,7 @@
|
||||
name="name"
|
||||
class="form-control"
|
||||
ng-model="currentGroup.name"
|
||||
ng-model-options="{ updateOn: 'submit' }"
|
||||
ng-change="checkForChanges()"
|
||||
type="text"
|
||||
required>
|
||||
</input>
|
||||
@ -360,7 +360,7 @@
|
||||
name="email"
|
||||
class="form-control"
|
||||
ng-model="currentGroup.email"
|
||||
ng-model-options="{ updateOn: 'submit' }"
|
||||
ng-change="checkForChanges()"
|
||||
type="text"
|
||||
required>
|
||||
</input>
|
||||
@ -389,7 +389,7 @@
|
||||
name="description"
|
||||
class="form-control"
|
||||
ng-model="currentGroup.description"
|
||||
ng-model-options="{ updateOn: 'submit' }"
|
||||
ng-change="checkForChanges()"
|
||||
type="text">
|
||||
</input>
|
||||
<span class="help-block">
|
||||
@ -399,7 +399,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="edit-group-button" class="btn btn-primary pull-right">Update</button>
|
||||
<button id="edit-group-button" class="btn btn-primary pull-right" ng-disabled="submitEditGroupForm.$invalid || !hasChanges">Update</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" ng-click="closeEditModal()">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -67,6 +67,7 @@
|
||||
<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>
|
||||
@ -86,6 +87,9 @@
|
||||
<div class="panel-body">
|
||||
<div class="vinyldns-panel-top">
|
||||
<div class="btn-group">
|
||||
<span class="modal fade" id="loader" tabindex="-1" role="dialog" >
|
||||
<span class="spinner" ></span>
|
||||
</span>
|
||||
<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>
|
||||
|
@ -210,8 +210,8 @@ angular.module('controller.groups', []).controller('GroupsController', function
|
||||
handleError(error, 'groupsService::getGroups-failure');
|
||||
});
|
||||
}
|
||||
//Function for fetching list of valid domains
|
||||
|
||||
//Function for fetching list of valid domains
|
||||
$scope.validDomains=function getValidEmailDomains() {
|
||||
function success(response) {
|
||||
$log.debug('groupsService::listEmailDomains-success', response);
|
||||
@ -247,10 +247,25 @@ angular.module('controller.groups', []).controller('GroupsController', function
|
||||
|
||||
$scope.editGroup = function (groupInfo) {
|
||||
$scope.currentGroup = groupInfo;
|
||||
$scope.initialGroup = {
|
||||
name: $scope.currentGroup.name,
|
||||
email: $scope.currentGroup.email,
|
||||
description: $scope.currentGroup.description
|
||||
};
|
||||
$scope.hasChanges = false;
|
||||
$scope.validDomains();
|
||||
$("#modal_edit_group").modal("show");
|
||||
};
|
||||
|
||||
// Function to check for changes
|
||||
$scope.checkForChanges = function() {
|
||||
$scope.hasChanges =
|
||||
$scope.currentGroup.name !== $scope.initialGroup.name ||
|
||||
$scope.currentGroup.email !== $scope.initialGroup.email ||
|
||||
($scope.currentGroup.description !== $scope.initialGroup.description &&
|
||||
!($scope.currentGroup.description === "" && $scope.initialGroup.description === undefined));
|
||||
};
|
||||
|
||||
$scope.getGroupAndUpdate = function(groupId, name, email, description) {
|
||||
function success(response) {
|
||||
$log.debug('groupsService::getGroup-success');
|
||||
@ -281,6 +296,7 @@ angular.module('controller.groups', []).controller('GroupsController', function
|
||||
return groupsService.updateGroup(groupId, payload)
|
||||
.then(success)
|
||||
.catch(function (error) {
|
||||
$scope.closeEditModal();
|
||||
handleError(error, 'groupsService::updateGroup-failure');
|
||||
});
|
||||
}
|
||||
|
@ -77,7 +77,16 @@ angular.module('service.records', [])
|
||||
"recordTypeSort": recordTypeSort
|
||||
};
|
||||
var url = utilityService.urlBuilder("/api/zones/"+id+"/recordsets", params);
|
||||
return $http.get(url);
|
||||
let loader = $("#loader");
|
||||
loader.modal({
|
||||
backdrop: "static", //remove ability to close modal with click
|
||||
keyboard: false, //remove option to close with keyboard
|
||||
show: true //Display loader!
|
||||
})
|
||||
let promis = $http.get(url);
|
||||
// Hide loader when api gets response
|
||||
promis.then(()=>loader.modal("hide"), ()=>loader.modal("hide"))
|
||||
return promis;
|
||||
};
|
||||
|
||||
this.getRecordSet = function (rsid) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
|
||||
# LDAP container hosting example users
|
||||
@ -9,7 +7,7 @@ services:
|
||||
ports:
|
||||
- "19004:19004"
|
||||
|
||||
# Integration image hosting r53, sns, sqs, bind, and mysql
|
||||
# Integration image hosting r53, sns, sqs, bind and mysql
|
||||
integration:
|
||||
container_name: "vinyldns-api-integration"
|
||||
hostname: "vinyldns-integration"
|
||||
|
@ -1 +1 @@
|
||||
version in ThisBuild := "0.20.0"
|
||||
version in ThisBuild := "0.20.1"
|
||||
|
Loading…
x
Reference in New Issue
Block a user