add-domain-setup-validation #71
@ -1,10 +1,14 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import net.hostsharing.hsadminng.system.SystemProcess;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static net.hostsharing.hsadminng.hs.validation.ArrayProperty.arrayOf;
|
||||
import static net.hostsharing.hsadminng.hs.validation.BooleanProperty.booleanProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerProperty.integerProperty;
|
||||
@ -17,8 +21,7 @@ class HsDomainDnsSetupHostingAssetValidator extends HsHostingAssetEntityValidato
|
||||
static final String RR_REGEX_TTL = "(([1-9][0-9]*[mMhHdDwW]{0,1})+\\s+)*";
|
||||
static final String RR_REGEX_IN = "IN\\s+"; // record class IN for Internet
|
||||
static final String RR_RECORD_TYPE = "[A-Z]+\\s+";
|
||||
static final String RR_RECORD_DATA_X = "([a-z0-9\\.-]+|\"[^\"]*\")\\s*"; // FIXME: (...) and multiline?
|
||||
static final String RR_RECORD_DATA = "([a-z0-9\\.-]+|\\([^\\)]*\\)|\"[^\"]*\")\\s*";
|
||||
static final String RR_RECORD_DATA = "[^;].*";
|
||||
static final String RR_COMMENT = "(;.*)*";
|
||||
|
||||
static final String RR_REGEX_TTL_IN =
|
||||
@ -60,6 +63,22 @@ class HsDomainDnsSetupHostingAssetValidator extends HsHostingAssetEntityValidato
|
||||
return Pattern.compile("^" + assetEntity.getParentAsset().getIdentifier() + "$");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public List<String> validateContext(final HsHostingAssetEntity assetEntity) {
|
||||
final var result = super.validateContext(assetEntity);
|
||||
|
||||
// TODO.spec: define which checks should get raised to error level
|
||||
final var namedCheckZone = new SystemProcess("named-checkzone", assetEntity.getIdentifier());
|
||||
if (namedCheckZone.execute(toZonefileString(assetEntity)) != 0) {
|
||||
// yes, named-checkzone writes error messages to stdout
|
||||
stream(namedCheckZone.getStdOut().split("\n"))
|
||||
.map(line -> line.replaceAll(" stream-0x[0-9a-f:]+", ""))
|
||||
.forEach(result::add);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String toZonefileString(final HsHostingAssetEntity assetEntity) {
|
||||
return """
|
||||
$ORIGIN {domain}.
|
||||
|
@ -10,7 +10,6 @@ import org.junit.jupiter.api.Test;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_DNS_SETUP;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_COMMENT;
|
||||
@ -35,6 +34,7 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
||||
.identifier("example.org")
|
||||
.config(Map.ofEntries(
|
||||
entry("user-RR", Array.of(
|
||||
hsh-michaelhoennig marked this conversation as resolved
|
||||
"@ 1814400 IN XXX example.org. root.example.org ( 1234 10800 900 604800 86400 )",
|
||||
"www IN CNAME example.com. ; www.example.com is an alias for example.com",
|
||||
"test1 IN 1h30m CNAME example.com.",
|
||||
"test2 1h30m IN CNAME example.com.",
|
||||
@ -94,7 +94,7 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
||||
"{type=boolean, propertyName=auto-WILDCARD-AAAA-RR, defaultValue=true}",
|
||||
"{type=boolean, propertyName=auto-WILDCARD-DKIM-RR, defaultValue=true}",
|
||||
"{type=boolean, propertyName=auto-WILDCARD-SPF-RR, defaultValue=true}",
|
||||
"{type=string[], propertyName=user-RR, elementsOf={type=string, propertyName=user-RR, matchesRegEx=[([a-z0-9\\.-]+|@)\\s+(([1-9][0-9]*[mMhHdDwW]{0,1})+\\s+)*IN\\s+[A-Z]+\\s+([a-z0-9\\.-]+|\\([^\\)]*\\)|\"[^\"]*\")\\s*(;.*)*, ([a-z0-9\\.-]+|@)\\s+IN\\s+(([1-9][0-9]*[mMhHdDwW]{0,1})+\\s+)*[A-Z]+\\s+([a-z0-9\\.-]+|\\([^\\)]*\\)|\"[^\"]*\")\\s*(;.*)*], required=true}}"
|
||||
"{type=string[], propertyName=user-RR, elementsOf={type=string, propertyName=user-RR, matchesRegEx=[([a-z0-9\\.-]+|@)\\s+(([1-9][0-9]*[mMhHdDwW]{0,1})+\\s+)*IN\\s+[A-Z]+\\s+[^;].*(;.*)*, ([a-z0-9\\.-]+|@)\\s+IN\\s+(([1-9][0-9]*[mMhHdDwW]{0,1})+\\s+)*[A-Z]+\\s+[^;].*(;.*)*], required=true}}"
|
||||
);
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
||||
@Test
|
||||
void generatesZonefile() {
|
||||
// given
|
||||
final var givenEntity = validEntityBuilder().identifier("example.org").build();
|
||||
final var givenEntity = validEntityBuilder().build();
|
||||
final var validator = (HsDomainDnsSetupHostingAssetValidator) HsHostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||
|
||||
// when
|
||||
@ -164,10 +164,46 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
||||
@ 1814400 IN SOA example.org. root.example.org ( 1999010100 10800 900 604800 86400 )
|
||||
@ IN NS ns
|
||||
|
||||
@ 1814400 IN XXX example.org. root.example.org ( 1234 10800 900 604800 86400 )
|
||||
www IN CNAME example.com. ; www.example.com is an alias for example.com
|
||||
test1 IN 1h30m CNAME example.com.
|
||||
test2 1h30m IN CNAME example.com.
|
||||
ns IN A 192.0.2.2; IPv4 address for ns.example.com
|
||||
""");
|
||||
}
|
||||
|
||||
@Test
|
||||
void acceptsValidEntity() {
|
||||
// given
|
||||
final var givenEntity = validEntityBuilder().build();
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||
|
||||
// when
|
||||
final var errors = validator.validateEntity(givenEntity);
|
||||
|
||||
// then
|
||||
assertThat(errors).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsInvalidEntity() {
|
||||
// given
|
||||
final var givenEntity = validEntityBuilder().config(Map.ofEntries(
|
||||
entry("user-RR", Array.of(
|
||||
"example.org. 1814400 IN SOA example.org. root.example.org (1234 10800 900 604800 86400)"
|
||||
))
|
||||
))
|
||||
.build();
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||
|
||||
// when
|
||||
final var errors = validator.validateContext(givenEntity);
|
||||
|
||||
// then
|
||||
assertThat(errors).containsExactlyInAnyOrder(
|
||||
"dns_master_load: example.org: multiple RRs of singleton type",
|
||||
"zone example.org/IN: loading from master file (null) failed: multiple RRs of singleton type",
|
||||
"zone example.org/IN: not loaded due to errors."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user
add test for invalid user-rr