import-hosting-domain-assets (#84)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #84
This commit is contained in:
parent
085876c772
commit
5046e9a296
@ -33,4 +33,38 @@
|
|||||||
<RunAsTest>true</RunAsTest>
|
<RunAsTest>true</RunAsTest>
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<configuration default="false" name="ImportOfficeData" type="GradleRunConfiguration" factoryName="Gradle">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="env">
|
||||||
|
<map>
|
||||||
|
<entry key="HSADMINNG_MIGRATION_DATA_PATH" value="migration" />
|
||||||
|
<entry key="HSADMINNG_POSTGRES_ADMIN_USERNAME" value="admin" />
|
||||||
|
<entry key="HSADMINNG_POSTGRES_RESTRICTED_USERNAME" value="restricted" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" value="" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value=":importOfficeData" />
|
||||||
|
<option value="--tests" />
|
||||||
|
<option value=""net.hostsharing.hsadminng.hs.office.migration.ImportOfficeData"" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<EXTENSION ID="com.intellij.execution.ExternalSystemRunConfigurationJavaExtension">
|
||||||
|
<extension name="coverage" sample_coverage="false" />
|
||||||
|
</EXTENSION>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>true</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
</component>
|
</component>
|
@ -15,15 +15,16 @@ import static net.hostsharing.hsadminng.hs.validation.BooleanProperty.booleanPro
|
|||||||
import static net.hostsharing.hsadminng.hs.validation.IntegerProperty.integerProperty;
|
import static net.hostsharing.hsadminng.hs.validation.IntegerProperty.integerProperty;
|
||||||
import static net.hostsharing.hsadminng.hs.validation.StringProperty.stringProperty;
|
import static net.hostsharing.hsadminng.hs.validation.StringProperty.stringProperty;
|
||||||
|
|
||||||
class HsDomainDnsSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
// TODO.impl: make package private once we've migrated the legacy data
|
||||||
|
public class HsDomainDnsSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
||||||
|
|
||||||
// according to RFC 1035 (section 5) and RFC 1034
|
// according to RFC 1035 (section 5) and RFC 1034
|
||||||
static final String RR_REGEX_NAME = "([a-z0-9\\.-]+|@)\\s+";
|
static final String RR_REGEX_NAME = "(\\*\\.)?([a-zA-Z0-9\\._-]+|@)[ \t]+";
|
||||||
static final String RR_REGEX_TTL = "(([1-9][0-9]*[mMhHdDwW]{0,1})+\\s+)*";
|
static final String RR_REGEX_TTL = "(([1-9][0-9]*[mMhHdDwW]?)+[ \t]+)?";
|
||||||
static final String RR_REGEX_IN = "IN\\s+"; // record class IN for Internet
|
static final String RR_REGEX_IN = "[iI][nN][ \t]+"; // record class IN for Internet
|
||||||
static final String RR_RECORD_TYPE = "[A-Z]+\\s+";
|
static final String RR_RECORD_TYPE = "[a-zA-Z]+[ \t]+";
|
||||||
static final String RR_RECORD_DATA = "[^;].*";
|
static final String RR_RECORD_DATA = "(([^;]+)|(\".*\")|(\\(.*\\)))[ \t]*";
|
||||||
static final String RR_COMMENT = "(;.*)*";
|
static final String RR_COMMENT = "(;.*)?";
|
||||||
|
|
||||||
static final String RR_REGEX_TTL_IN =
|
static final String RR_REGEX_TTL_IN =
|
||||||
RR_REGEX_NAME + RR_REGEX_TTL + RR_REGEX_IN + RR_RECORD_TYPE + RR_RECORD_DATA + RR_COMMENT;
|
RR_REGEX_NAME + RR_REGEX_TTL + RR_REGEX_IN + RR_RECORD_TYPE + RR_RECORD_DATA + RR_COMMENT;
|
||||||
@ -32,26 +33,27 @@ class HsDomainDnsSetupHostingAssetValidator extends HostingAssetEntityValidator
|
|||||||
RR_REGEX_NAME + RR_REGEX_IN + RR_REGEX_TTL + RR_RECORD_TYPE + RR_RECORD_DATA + RR_COMMENT;
|
RR_REGEX_NAME + RR_REGEX_IN + RR_REGEX_TTL + RR_RECORD_TYPE + RR_RECORD_DATA + RR_COMMENT;
|
||||||
public static final String IDENTIFIER_SUFFIX = "|DNS";
|
public static final String IDENTIFIER_SUFFIX = "|DNS";
|
||||||
|
|
||||||
|
private static List<String> zoneFileErrors = null; // TODO.impl: remove once legacy data is migrated
|
||||||
|
|
||||||
HsDomainDnsSetupHostingAssetValidator() {
|
HsDomainDnsSetupHostingAssetValidator() {
|
||||||
super(
|
super(
|
||||||
DOMAIN_DNS_SETUP,
|
DOMAIN_DNS_SETUP,
|
||||||
AlarmContact.isOptional(),
|
AlarmContact.isOptional(),
|
||||||
|
|
||||||
integerProperty("TTL").min(0).withDefault(21600),
|
integerProperty("TTL").min(0).withDefault(21600),
|
||||||
booleanProperty("auto-SOA-RR").withDefault(true),
|
booleanProperty("auto-SOA").withDefault(true),
|
||||||
booleanProperty("auto-NS-RR").withDefault(true),
|
booleanProperty("auto-NS-RR").withDefault(true),
|
||||||
booleanProperty("auto-MX-RR").withDefault(true),
|
booleanProperty("auto-MX-RR").withDefault(true),
|
||||||
booleanProperty("auto-A-RR").withDefault(true),
|
booleanProperty("auto-A-RR").withDefault(true),
|
||||||
booleanProperty("auto-AAAA-RR").withDefault(true),
|
booleanProperty("auto-AAAA-RR").withDefault(true),
|
||||||
booleanProperty("auto-MAILSERVICES-RR").withDefault(true),
|
booleanProperty("auto-MAILSERVICES-RR").withDefault(true),
|
||||||
booleanProperty("auto-AUTOCONFIG-RR").withDefault(true), // TODO.spec: does that already exist?
|
booleanProperty("auto-AUTOCONFIG-RR").withDefault(true),
|
||||||
booleanProperty("auto-AUTODISCOVER-RR").withDefault(true),
|
booleanProperty("auto-AUTODISCOVER-RR").withDefault(true),
|
||||||
booleanProperty("auto-DKIM-RR").withDefault(true),
|
booleanProperty("auto-DKIM-RR").withDefault(true),
|
||||||
booleanProperty("auto-SPF-RR").withDefault(true),
|
booleanProperty("auto-SPF-RR").withDefault(true),
|
||||||
booleanProperty("auto-WILDCARD-MX-RR").withDefault(true),
|
booleanProperty("auto-WILDCARD-MX-RR").withDefault(true),
|
||||||
booleanProperty("auto-WILDCARD-A-RR").withDefault(true),
|
booleanProperty("auto-WILDCARD-A-RR").withDefault(true),
|
||||||
booleanProperty("auto-WILDCARD-AAAA-RR").withDefault(true),
|
booleanProperty("auto-WILDCARD-AAAA-RR").withDefault(true),
|
||||||
booleanProperty("auto-WILDCARD-DKIM-RR").withDefault(true), // TODO.spec: check, if that really works
|
|
||||||
booleanProperty("auto-WILDCARD-SPF-RR").withDefault(true),
|
booleanProperty("auto-WILDCARD-SPF-RR").withDefault(true),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
stringProperty("user-RR").matchesRegEx(RR_REGEX_TTL_IN, RR_REGEX_IN_TTL).required()
|
stringProperty("user-RR").matchesRegEx(RR_REGEX_TTL_IN, RR_REGEX_IN_TTL).required()
|
||||||
@ -60,7 +62,7 @@ class HsDomainDnsSetupHostingAssetValidator extends HostingAssetEntityValidator
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Pattern identifierPattern(final HsHostingAsset assetEntity) {
|
protected Pattern identifierPattern(final HsHostingAsset assetEntity) {
|
||||||
return Pattern.compile("^" + Pattern.quote(assetEntity.getParentAsset().getIdentifier() + IDENTIFIER_SUFFIX) + "$");
|
return Pattern.compile("^" + Pattern.quote(assetEntity.getParentAsset().getIdentifier() + IDENTIFIER_SUFFIX) + "$");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -78,33 +80,105 @@ class HsDomainDnsSetupHostingAssetValidator extends HostingAssetEntityValidator
|
|||||||
|
|
||||||
// TODO.spec: define which checks should get raised to error level
|
// TODO.spec: define which checks should get raised to error level
|
||||||
final var namedCheckZone = new SystemProcess("named-checkzone", fqdn(assetEntity));
|
final var namedCheckZone = new SystemProcess("named-checkzone", fqdn(assetEntity));
|
||||||
if (namedCheckZone.execute(toZonefileString(assetEntity)) != 0) {
|
final var zonefileString = toZonefileString(assetEntity);
|
||||||
// yes, named-checkzone writes error messages to stdout
|
final var zoneFileErrorResult = zoneFileErrors != null ? zoneFileErrors : result;
|
||||||
|
if (namedCheckZone.execute(zonefileString) != 0) {
|
||||||
|
// yes, named-checkzone writes error messages to stdout, not stderr
|
||||||
stream(namedCheckZone.getStdOut().split("\n"))
|
stream(namedCheckZone.getStdOut().split("\n"))
|
||||||
.map(line -> line.replaceAll(" stream-0x[0-9a-f:]+", ""))
|
.map(line -> line.replaceAll(" stream-0x[0-9a-f]+:", "line "))
|
||||||
.forEach(result::add);
|
.map(line -> "[" + assetEntity.getIdentifier() + "] " + line)
|
||||||
|
.forEach(zoneFileErrorResult::add);
|
||||||
|
if (!namedCheckZone.getStdErr().isEmpty()) {
|
||||||
|
result.add("unexpected stderr output for " + namedCheckZone.getCommand() + ": " + namedCheckZone.getStdErr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String toZonefileString(final HsHostingAsset assetEntity) {
|
String toZonefileString(final HsHostingAsset assetEntity) {
|
||||||
// TODO.spec: we need to expand the templates (auto-...) in the same way as in Saltstack
|
// TODO.spec: we need to expand the templates (auto-...) in the same way as in Saltstack, with proper IP-numbers etc.
|
||||||
return """
|
return """
|
||||||
$ORIGIN {domain}.
|
$TTL {ttl}
|
||||||
$TTL {ttl}
|
|
||||||
|
|
||||||
; these records are just placeholders to create a valid zonefile for the validation
|
{auto-SOA}
|
||||||
@ 1814400 IN SOA {domain}. root.{domain} ( 1999010100 10800 900 604800 86400 )
|
{auto-NS-RR}
|
||||||
@ IN NS ns
|
{auto-MX-RR}
|
||||||
|
{auto-A-RR}
|
||||||
|
{auto-AAAA-RR}
|
||||||
|
{auto-DKIM-RR}
|
||||||
|
{auto-SPF-RR}
|
||||||
|
|
||||||
{userRRs}
|
{auto-WILDCARD-MX-RR}
|
||||||
"""
|
{auto-WILDCARD-A-RR}
|
||||||
.replace("{domain}", fqdn(assetEntity))
|
{auto-WILDCARD-AAAA-RR}
|
||||||
.replace("{ttl}", getPropertyValue(assetEntity, "TTL"))
|
{auto-WILDCARD-SPF-RR}
|
||||||
.replace("{userRRs}", getPropertyValues(assetEntity, "user-RR") );
|
|
||||||
|
{userRRs}
|
||||||
|
"""
|
||||||
|
.replace("{ttl}", assetEntity.getDirectValue("TTL", Integer.class, 43200).toString())
|
||||||
|
.replace("{auto-SOA}", assetEntity.getDirectValue("auto-SOA", Boolean.class, false).equals(true)
|
||||||
|
? """
|
||||||
|
{domain}. IN SOA h00.hostsharing.net. hostmaster.hostsharing.net. (
|
||||||
|
1303649373 ; serial secs since Jan 1 1970
|
||||||
|
6H ; refresh (>=10000)
|
||||||
|
1H ; retry (>=1800)
|
||||||
|
1W ; expire
|
||||||
|
1H ; minimum
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
: "; no auto-SOA"
|
||||||
|
)
|
||||||
|
.replace("{auto-NS-RR}", assetEntity.getDirectValue("auto-NS-RR", Boolean.class, true)
|
||||||
|
? """
|
||||||
|
{domain}. IN NS dns1.hostsharing.net.
|
||||||
|
{domain}. IN NS dns2.hostsharing.net.
|
||||||
|
{domain}. IN NS dns3.hostsharing.net.
|
||||||
|
"""
|
||||||
|
: "; no auto-NS-RR")
|
||||||
|
.replace("{auto-MX-RR}", assetEntity.getDirectValue("auto-MX-RR", Boolean.class, true)
|
||||||
|
? """
|
||||||
|
{domain}. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
{domain}. IN MX 30 mailin2.hostsharing.net.
|
||||||
|
{domain}. IN MX 30 mailin3.hostsharing.net.
|
||||||
|
"""
|
||||||
|
: "; no auto-MX-RR")
|
||||||
|
.replace("{auto-A-RR}", assetEntity.getDirectValue("auto-A-RR", Boolean.class, true)
|
||||||
|
? "{domain}. IN A 83.223.95.160" // arbitrary IP-number
|
||||||
|
: "; no auto-A-RR")
|
||||||
|
.replace("{auto-AAAA-RR}", assetEntity.getDirectValue("auto-AAA-RR", Boolean.class, true)
|
||||||
|
? "{domain}. IN AAAA 2a01:37:1000::53df:5fa0:0" // arbitrary IP-number
|
||||||
|
: "; no auto-AAAA-RR")
|
||||||
|
.replace("{auto-DKIM-RR}", assetEntity.getDirectValue("auto-DKIM-RR", Boolean.class, true)
|
||||||
|
? "default._domainkey 21600 IN TXT \"v=DKIM1; h=sha256; k=rsa; s=email; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmdM9d15bqe94zbHVcKKpUF875XoCWHKRap/sG3NJZ9xZ/BjfGXmqoEYeFNpX3CB7pOXhH5naq4N+6gTjArTviAiVThHXyebhrxaf1dVS4IUC6raTEyQrWPZUf7ZxXmcCYvOdV4jIQ8GRfxwxqibIJcmMiufXTLIgRUif5uaTgFwIDAQAB\""
|
||||||
|
: "; no auto-DKIM-RR")
|
||||||
|
.replace("{auto-SPF-RR}", assetEntity.getDirectValue("auto-SPF-RR", Boolean.class, true)
|
||||||
|
? "{domain}. IN TXT \"v=spf1 include:spf.hostsharing.net ?all\""
|
||||||
|
: "; no auto-SPF-RR")
|
||||||
|
.replace("{auto-WILDCARD-MX-RR}", assetEntity.getDirectValue("auto-SPF-RR", Boolean.class, true)
|
||||||
|
? """
|
||||||
|
*.{domain}. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
*.{domain}. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
*.{domain}. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
"""
|
||||||
|
: "; no auto-WILDCARD-MX-RR")
|
||||||
|
.replace("{auto-WILDCARD-A-RR}", assetEntity.getDirectValue("auto-WILDCARD-A-RR", Boolean.class, true)
|
||||||
|
? "*.{domain}. IN A 83.223.95.160" // arbitrary IP-number
|
||||||
|
: "; no auto-WILDCARD-A-RR")
|
||||||
|
.replace("{auto-WILDCARD-AAAA-RR}", assetEntity.getDirectValue("auto-WILDCARD-AAAA-RR", Boolean.class, true)
|
||||||
|
? "*.{domain}. IN AAAA 2a01:37:1000::53df:5fa0:0" // arbitrary IP-number
|
||||||
|
: "; no auto-WILDCARD-AAAA-RR")
|
||||||
|
.replace("{auto-WILDCARD-SPF-RR}", assetEntity.getDirectValue("auto-WILDCARD-SPF-RR", Boolean.class, true)
|
||||||
|
? "*.{domain}. IN TXT \"v=spf1 include:spf.hostsharing.net ?all\""
|
||||||
|
: "; no auto-WILDCARD-SPF-RR")
|
||||||
|
.replace("{domain}", fqdn(assetEntity))
|
||||||
|
.replace("{userRRs}", getPropertyValues(assetEntity, "user-RR"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String fqdn(final HsHostingAsset assetEntity) {
|
private String fqdn(final HsHostingAsset assetEntity) {
|
||||||
return assetEntity.getIdentifier().substring(0, assetEntity.getIdentifier().length()-IDENTIFIER_SUFFIX.length());
|
return assetEntity.getIdentifier().substring(0, assetEntity.getIdentifier().length() - IDENTIFIER_SUFFIX.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addZonefileErrorsTo(final List<String> zoneFileErrors) {
|
||||||
|
HsDomainDnsSetupHostingAssetValidator.zoneFileErrors = zoneFileErrors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ import static net.hostsharing.hsadminng.hs.validation.StringProperty.stringPrope
|
|||||||
class HsDomainHttpSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
class HsDomainHttpSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
||||||
|
|
||||||
public static final String IDENTIFIER_SUFFIX = "|HTTP";
|
public static final String IDENTIFIER_SUFFIX = "|HTTP";
|
||||||
public static final String FILESYSTEM_PATH = "^/";
|
public static final String FILESYSTEM_PATH = "^/.*";
|
||||||
public static final String PARTIAL_DOMAIN_NAME_REGEX = "(?!-)[A-Za-z0-9-]{1,63}(?<!-)";
|
public static final String SUBDOMAIN_NAME_REGEX = "(\\*|(?!-)[A-Za-z0-9-]{1,63}(?<!-))";
|
||||||
|
|
||||||
HsDomainHttpSetupHostingAssetValidator() {
|
HsDomainHttpSetupHostingAssetValidator() {
|
||||||
super(
|
super(
|
||||||
@ -37,7 +37,7 @@ class HsDomainHttpSetupHostingAssetValidator extends HostingAssetEntityValidator
|
|||||||
stringProperty("passenger-python").matchesRegEx(FILESYSTEM_PATH).provided("/usr/bin/python3").withDefault("/usr/bin/python3"),
|
stringProperty("passenger-python").matchesRegEx(FILESYSTEM_PATH).provided("/usr/bin/python3").withDefault("/usr/bin/python3"),
|
||||||
stringProperty("passenger-ruby").matchesRegEx(FILESYSTEM_PATH).provided("/usr/bin/ruby").withDefault("/usr/bin/ruby"),
|
stringProperty("passenger-ruby").matchesRegEx(FILESYSTEM_PATH).provided("/usr/bin/ruby").withDefault("/usr/bin/ruby"),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
stringProperty("subdomains").matchesRegEx(PARTIAL_DOMAIN_NAME_REGEX).required()
|
stringProperty("subdomains").matchesRegEx(SUBDOMAIN_NAME_REGEX).required()
|
||||||
).optional());
|
).optional());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMA
|
|||||||
|
|
||||||
class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
||||||
|
|
||||||
public static final String FQDN_REGEX = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}";
|
public static final String FQDN_REGEX = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,12}";
|
||||||
|
|
||||||
private final Pattern identifierPattern;
|
private final Pattern identifierPattern;
|
||||||
|
|
||||||
|
@ -145,4 +145,8 @@ public abstract class HsEntityValidator<E extends PropertiesProvider> {
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ValidatableProperty<?, ?> getProperty(final String propertyName) {
|
||||||
|
return stream(propertyValidators).filter(pv -> pv.propertyName().equals(propertyName)).findFirst().orElse(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,27 @@
|
|||||||
package net.hostsharing.hsadminng.mapper;
|
package net.hostsharing.hsadminng.mapper;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static java.util.stream.Collectors.joining;
|
|
||||||
|
|
||||||
/** This class wraps another (usually persistent) map and
|
/** This class wraps another (usually persistent) map and
|
||||||
* supports applying `PatchMap` as well as a toString method with stable entry order.
|
* supports applying `PatchMap` as well as a toString method with stable entry order.
|
||||||
*/
|
*/
|
||||||
public class PatchableMapWrapper<T> implements Map<String, T> {
|
public class PatchableMapWrapper<T> implements Map<String, T> {
|
||||||
|
|
||||||
|
private static final ObjectMapper jsonWriter = new ObjectMapper()
|
||||||
|
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
|
||||||
|
.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||||
|
|
||||||
private final Map<String, T> delegate;
|
private final Map<String, T> delegate;
|
||||||
|
|
||||||
private PatchableMapWrapper(final Map<String, T> map) {
|
private PatchableMapWrapper(final Map<String, T> map) {
|
||||||
@ -53,24 +58,9 @@ public class PatchableMapWrapper<T> implements Map<String, T> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{\n"
|
return jsonWriter.writeValueAsString(delegate);
|
||||||
+ (
|
|
||||||
keySet().stream().sorted()
|
|
||||||
.map(k -> " \"" + k + "\": " + formatted(get(k))))
|
|
||||||
.collect(joining(",\n")
|
|
||||||
)
|
|
||||||
+ "\n}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object formatted(final Object value) {
|
|
||||||
if ( value == null || value instanceof Number || value instanceof Boolean ) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
if ( value.getClass().isArray() ) {
|
|
||||||
return "\"" + Arrays.toString( (Object[]) value) + "\"";
|
|
||||||
}
|
|
||||||
return "\"" + value + "\"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- below just delegating methods --------------------------------
|
// --- below just delegating methods --------------------------------
|
||||||
|
@ -21,6 +21,11 @@ public class SystemProcess {
|
|||||||
this.processBuilder = new ProcessBuilder(command);
|
this.processBuilder = new ProcessBuilder(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return processBuilder.command().toString();
|
||||||
|
}
|
||||||
|
|
||||||
public int execute() throws IOException, InterruptedException {
|
public int execute() throws IOException, InterruptedException {
|
||||||
final var process = processBuilder.start();
|
final var process = processBuilder.start();
|
||||||
stdOut = fetchOutput(process.getInputStream()); // yeah, twisted ProcessBuilder API
|
stdOut = fetchOutput(process.getInputStream()); // yeah, twisted ProcessBuilder API
|
||||||
|
@ -35,12 +35,27 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
.assignedToAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
.assignedToAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
||||||
.identifier("example.org|DNS")
|
.identifier("example.org|DNS")
|
||||||
.config(Map.ofEntries(
|
.config(Map.ofEntries(
|
||||||
|
entry("TTL", 21600),
|
||||||
|
entry("auto-SOA", true),
|
||||||
|
entry("auto-NS-RR", true),
|
||||||
|
entry("auto-MX-RR", true),
|
||||||
|
entry("auto-A-RR", true),
|
||||||
|
entry("auto-AAAA-RR", true),
|
||||||
|
entry("auto-MAILSERVICES-RR", true),
|
||||||
|
entry("auto-AUTOCONFIG-RR", true),
|
||||||
|
entry("auto-AUTODISCOVER-RR", true),
|
||||||
|
entry("auto-DKIM-RR", true),
|
||||||
|
entry("auto-SPF-RR", true),
|
||||||
|
entry("auto-WILDCARD-MX-RR", true),
|
||||||
|
entry("auto-WILDCARD-A-RR", true),
|
||||||
|
entry("auto-WILDCARD-AAAA-RR", true),
|
||||||
|
entry("auto-WILDCARD-SPF-RR", true),
|
||||||
entry("user-RR", Array.of(
|
entry("user-RR", Array.of(
|
||||||
"@ 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",
|
"www IN CNAME example.com. ; www.example.com is an alias for example.com",
|
||||||
"test1 IN 1h30m CNAME example.com.",
|
"test1 IN 1h30m CNAME example.com.",
|
||||||
"test2 1h30m IN CNAME example.com.",
|
"test2 1h30m IN CNAME example.com.",
|
||||||
"ns IN A 192.0.2.2; IPv4 address for ns.example.com")
|
"ns IN A 192.0.2.2; IPv4 address for ns.example.com",
|
||||||
|
"_acme-challenge.PAULCHEN-VS.core.example.org. 60 IN CNAME _acme-challenge.core.example.org.acme-pki.de.")
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -53,7 +68,7 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||||
"{type=integer, propertyName=TTL, min=0, defaultValue=21600}",
|
"{type=integer, propertyName=TTL, min=0, defaultValue=21600}",
|
||||||
"{type=boolean, propertyName=auto-SOA-RR, defaultValue=true}",
|
"{type=boolean, propertyName=auto-SOA, defaultValue=true}",
|
||||||
"{type=boolean, propertyName=auto-NS-RR, defaultValue=true}",
|
"{type=boolean, propertyName=auto-NS-RR, defaultValue=true}",
|
||||||
"{type=boolean, propertyName=auto-MX-RR, defaultValue=true}",
|
"{type=boolean, propertyName=auto-MX-RR, defaultValue=true}",
|
||||||
"{type=boolean, propertyName=auto-A-RR, defaultValue=true}",
|
"{type=boolean, propertyName=auto-A-RR, defaultValue=true}",
|
||||||
@ -66,9 +81,8 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
"{type=boolean, propertyName=auto-WILDCARD-MX-RR, defaultValue=true}",
|
"{type=boolean, propertyName=auto-WILDCARD-MX-RR, defaultValue=true}",
|
||||||
"{type=boolean, propertyName=auto-WILDCARD-A-RR, defaultValue=true}",
|
"{type=boolean, propertyName=auto-WILDCARD-A-RR, defaultValue=true}",
|
||||||
"{type=boolean, propertyName=auto-WILDCARD-AAAA-RR, defaultValue=true}",
|
"{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=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+IN\\s+(([1-9][0-9]*[mMhHdDwW]{0,1})+\\s+)*[A-Z]+\\s+[^;].*(;.*)*], required=true}}"
|
"{type=string[], propertyName=user-RR, elementsOf={type=string, propertyName=user-RR, matchesRegEx=[(\\*\\.)?([a-zA-Z0-9\\._-]+|@)[ \t]+(([1-9][0-9]*[mMhHdDwW]?)+[ \t]+)?[iI][nN][ \t]+[a-zA-Z]+[ \t]+(([^;]+)|(\".*\")|(\\(.*\\)))[ \t]*(;.*)?, (\\*\\.)?([a-zA-Z0-9\\._-]+|@)[ \t]+[iI][nN][ \t]+(([1-9][0-9]*[mMhHdDwW]?)+[ \t]+)?[a-zA-Z]+[ \t]+(([^;]+)|(\".*\")|(\\(.*\\)))[ \t]*(;.*)?], required=true}}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +149,7 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void acceptsValidEntity() {
|
void acceptsValidEntityItself() {
|
||||||
// given
|
// given
|
||||||
final var givenEntity = validEntityBuilder().build();
|
final var givenEntity = validEntityBuilder().build();
|
||||||
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||||
@ -147,6 +161,19 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
assertThat(errors).isEmpty();
|
assertThat(errors).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void acceptsValidEntityInContext() {
|
||||||
|
// given
|
||||||
|
final var givenEntity = validEntityBuilder().build();
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var errors = validator.validateContext(givenEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(errors).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void rejectsInvalidProperties() {
|
void rejectsInvalidProperties() {
|
||||||
// given
|
// given
|
||||||
@ -166,35 +193,56 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(result).containsExactlyInAnyOrder(
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
"'DOMAIN_DNS_SETUP:example.org|DNS.config.TTL' is expected to be of type Integer, but is of type String",
|
"'DOMAIN_DNS_SETUP:example.org|DNS.config.TTL' is expected to be of type Integer, but is of type String",
|
||||||
"'DOMAIN_DNS_SETUP:example.org|DNS.config.user-RR' is expected to match any of [([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+[^;].*(;.*)*] but '@ 1814400 IN 1814400 BAD1 TTL only allowed once' does not match any",
|
"'DOMAIN_DNS_SETUP:example.org|DNS.config.user-RR' is expected to match any of [(\\*\\.)?([a-zA-Z0-9\\._-]+|@)[ \t]+(([1-9][0-9]*[mMhHdDwW]?)+[ \t]+)?[iI][nN][ \t]+[a-zA-Z]+[ \t]+(([^;]+)|(\".*\")|(\\(.*\\)))[ \t]*(;.*)?, (\\*\\.)?([a-zA-Z0-9\\._-]+|@)[ \t]+[iI][nN][ \t]+(([1-9][0-9]*[mMhHdDwW]?)+[ \t]+)?[a-zA-Z]+[ \t]+(([^;]+)|(\".*\")|(\\(.*\\)))[ \t]*(;.*)?] but '@ 1814400 IN 1814400 BAD1 TTL only allowed once' does not match any",
|
||||||
"'DOMAIN_DNS_SETUP:example.org|DNS.config.user-RR' is expected to match any of [([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+[^;].*(;.*)*] but 'www BAD1 Record-Class missing / not enough columns' does not match any");
|
"'DOMAIN_DNS_SETUP:example.org|DNS.config.user-RR' is expected to match any of [(\\*\\.)?([a-zA-Z0-9\\._-]+|@)[ \t]+(([1-9][0-9]*[mMhHdDwW]?)+[ \t]+)?[iI][nN][ \t]+[a-zA-Z]+[ \t]+(([^;]+)|(\".*\")|(\\(.*\\)))[ \t]*(;.*)?, (\\*\\.)?([a-zA-Z0-9\\._-]+|@)[ \t]+[iI][nN][ \t]+(([1-9][0-9]*[mMhHdDwW]?)+[ \t]+)?[a-zA-Z]+[ \t]+(([^;]+)|(\".*\")|(\\(.*\\)))[ \t]*(;.*)?] but 'www BAD1 Record-Class missing / not enough columns' does not match any");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void validStringMatchesRegEx() {
|
void validNameMatchesRegEx() {
|
||||||
assertThat("@ ").matches(RR_REGEX_NAME);
|
assertThat("@ ").matches(RR_REGEX_NAME);
|
||||||
assertThat("ns ").matches(RR_REGEX_NAME);
|
assertThat("ns ").matches(RR_REGEX_NAME);
|
||||||
assertThat("example.com. ").matches(RR_REGEX_NAME);
|
assertThat("example.com. ").matches(RR_REGEX_NAME);
|
||||||
|
assertThat("example.ORG. ").matches(RR_REGEX_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validTtlMatchesRegEx() {
|
||||||
assertThat("12400 ").matches(RR_REGEX_TTL);
|
assertThat("12400 ").matches(RR_REGEX_TTL);
|
||||||
assertThat("12400\t\t ").matches(RR_REGEX_TTL);
|
assertThat("12400\t\t ").matches(RR_REGEX_TTL);
|
||||||
assertThat("12400 \t\t").matches(RR_REGEX_TTL);
|
assertThat("12400 \t\t").matches(RR_REGEX_TTL);
|
||||||
assertThat("1h30m ").matches(RR_REGEX_TTL);
|
assertThat("1h30m ").matches(RR_REGEX_TTL);
|
||||||
assertThat("30m ").matches(RR_REGEX_TTL);
|
assertThat("30m ").matches(RR_REGEX_TTL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validInMatchesRegEx() {
|
||||||
|
assertThat("in ").matches(RR_REGEX_IN);
|
||||||
assertThat("IN ").matches(RR_REGEX_IN);
|
assertThat("IN ").matches(RR_REGEX_IN);
|
||||||
assertThat("IN\t\t ").matches(RR_REGEX_IN);
|
assertThat("IN\t\t ").matches(RR_REGEX_IN);
|
||||||
assertThat("IN \t\t").matches(RR_REGEX_IN);
|
assertThat("IN \t\t").matches(RR_REGEX_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validRecordTypeMatchesRegEx() {
|
||||||
|
assertThat("a ").matches(RR_RECORD_TYPE);
|
||||||
assertThat("CNAME ").matches(RR_RECORD_TYPE);
|
assertThat("CNAME ").matches(RR_RECORD_TYPE);
|
||||||
assertThat("CNAME\t\t ").matches(RR_RECORD_TYPE);
|
assertThat("CNAME\t\t ").matches(RR_RECORD_TYPE);
|
||||||
assertThat("CNAME \t\t").matches(RR_RECORD_TYPE);
|
assertThat("CNAME \t\t").matches(RR_RECORD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validRecordDataMatchesRegEx() {
|
||||||
assertThat("example.com.").matches(RR_RECORD_DATA);
|
assertThat("example.com.").matches(RR_RECORD_DATA);
|
||||||
|
assertThat("example.com. ").matches(RR_RECORD_DATA);
|
||||||
assertThat("123.123.123.123").matches(RR_RECORD_DATA);
|
assertThat("123.123.123.123").matches(RR_RECORD_DATA);
|
||||||
|
assertThat("123.123.123.123 ").matches(RR_RECORD_DATA);
|
||||||
|
assertThat("_acme-challenge.core.example.org.acme-pki.de.").matches(RR_RECORD_DATA);
|
||||||
assertThat("(some more complex argument in parenthesis)").matches(RR_RECORD_DATA);
|
assertThat("(some more complex argument in parenthesis)").matches(RR_RECORD_DATA);
|
||||||
assertThat("\"some more complex argument; including a semicolon\"").matches(RR_RECORD_DATA);
|
assertThat("\"some more complex argument; including a semicolon\"").matches(RR_RECORD_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validCommentMatchesRegEx() {
|
||||||
assertThat("; whatever ; \" really anything").matches(RR_COMMENT);
|
assertThat("; whatever ; \" really anything").matches(RR_COMMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,18 +257,42 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(zonefile).isEqualTo("""
|
assertThat(zonefile).isEqualTo("""
|
||||||
$ORIGIN example.org.
|
|
||||||
$TTL 21600
|
$TTL 21600
|
||||||
|
|
||||||
; these records are just placeholders to create a valid zonefile for the validation
|
example.org. IN SOA h00.hostsharing.net. hostmaster.hostsharing.net. (
|
||||||
@ 1814400 IN SOA example.org. root.example.org ( 1999010100 10800 900 604800 86400 )
|
1303649373 ; serial secs since Jan 1 1970
|
||||||
@ IN NS ns
|
6H ; refresh (>=10000)
|
||||||
|
1H ; retry (>=1800)
|
||||||
|
1W ; expire
|
||||||
|
1H ; minimum
|
||||||
|
)
|
||||||
|
|
||||||
|
example.org. IN NS dns1.hostsharing.net.
|
||||||
|
example.org. IN NS dns2.hostsharing.net.
|
||||||
|
example.org. IN NS dns3.hostsharing.net.
|
||||||
|
|
||||||
|
example.org. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
example.org. IN MX 30 mailin2.hostsharing.net.
|
||||||
|
example.org. IN MX 30 mailin3.hostsharing.net.
|
||||||
|
|
||||||
|
example.org. IN A 83.223.95.160
|
||||||
|
example.org. IN AAAA 2a01:37:1000::53df:5fa0:0
|
||||||
|
default._domainkey 21600 IN TXT "v=DKIM1; h=sha256; k=rsa; s=email; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmdM9d15bqe94zbHVcKKpUF875XoCWHKRap/sG3NJZ9xZ/BjfGXmqoEYeFNpX3CB7pOXhH5naq4N+6gTjArTviAiVThHXyebhrxaf1dVS4IUC6raTEyQrWPZUf7ZxXmcCYvOdV4jIQ8GRfxwxqibIJcmMiufXTLIgRUif5uaTgFwIDAQAB"
|
||||||
|
example.org. IN TXT "v=spf1 include:spf.hostsharing.net ?all"
|
||||||
|
|
||||||
|
*.example.org. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
*.example.org. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
*.example.org. IN MX 30 mailin1.hostsharing.net.
|
||||||
|
|
||||||
|
*.example.org. IN A 83.223.95.160
|
||||||
|
*.example.org. IN AAAA 2a01:37:1000::53df:5fa0:0
|
||||||
|
*.example.org. IN TXT "v=spf1 include:spf.hostsharing.net ?all"
|
||||||
|
|
||||||
@ 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
|
www IN CNAME example.com. ; www.example.com is an alias for example.com
|
||||||
test1 IN 1h30m CNAME example.com.
|
test1 IN 1h30m CNAME example.com.
|
||||||
test2 1h30m IN CNAME example.com.
|
test2 1h30m IN CNAME example.com.
|
||||||
ns IN A 192.0.2.2; IPv4 address for ns.example.com
|
ns IN A 192.0.2.2; IPv4 address for ns.example.com
|
||||||
|
_acme-challenge.PAULCHEN-VS.core.example.org. 60 IN CNAME _acme-challenge.core.example.org.acme-pki.de.
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +301,8 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
// given
|
// given
|
||||||
final var givenEntity = validEntityBuilder().config(Map.ofEntries(
|
final var givenEntity = validEntityBuilder().config(Map.ofEntries(
|
||||||
entry("user-RR", Array.of(
|
entry("user-RR", Array.of(
|
||||||
"example.org. 1814400 IN SOA example.org. root.example.org (1234 10800 900 604800 86400)"
|
"example.org. 1814400 IN SOA example.org. root.example.org (1234 10800 900 604800 86400)",
|
||||||
|
"example.org. 1814400 IN SOA example.org. root.example.org (4321 10800 900 604800 86400)"
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
@ -240,9 +313,9 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(errors).containsExactlyInAnyOrder(
|
assertThat(errors).containsExactlyInAnyOrder(
|
||||||
"dns_master_load: example.org: multiple RRs of singleton type",
|
"[example.org|DNS] dns_master_load:line 26: example.org: multiple RRs of singleton type",
|
||||||
"zone example.org/IN: loading from master file (null) failed: multiple RRs of singleton type",
|
"[example.org|DNS] zone example.org/IN: loading from master file (null) failed: multiple RRs of singleton type",
|
||||||
"zone example.org/IN: not loaded due to errors."
|
"[example.org|DNS] zone example.org/IN: not loaded due to errors."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ class HsDomainHttpSetupHostingAssetValidatorUnitTest {
|
|||||||
.identifier("example.org|HTTP")
|
.identifier("example.org|HTTP")
|
||||||
.config(Map.ofEntries(
|
.config(Map.ofEntries(
|
||||||
entry("passenger-errorpage", true),
|
entry("passenger-errorpage", true),
|
||||||
|
entry("fcgi-php-bin", "/usr/bin/whatsoever"),
|
||||||
entry("subdomains", Array.of("www", "test")
|
entry("subdomains", Array.of("www", "test")
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
@ -54,10 +55,10 @@ class HsDomainHttpSetupHostingAssetValidatorUnitTest {
|
|||||||
"{type=boolean, propertyName=includes, defaultValue=true}",
|
"{type=boolean, propertyName=includes, defaultValue=true}",
|
||||||
"{type=boolean, propertyName=letsencrypt, defaultValue=true}",
|
"{type=boolean, propertyName=letsencrypt, defaultValue=true}",
|
||||||
"{type=boolean, propertyName=multiviews, defaultValue=true}",
|
"{type=boolean, propertyName=multiviews, defaultValue=true}",
|
||||||
"{type=string, propertyName=fcgi-php-bin, matchesRegEx=[^/], provided=[/usr/lib/cgi-bin/php], defaultValue=/usr/lib/cgi-bin/php}",
|
"{type=string, propertyName=fcgi-php-bin, matchesRegEx=[^/.*], provided=[/usr/lib/cgi-bin/php], defaultValue=/usr/lib/cgi-bin/php}",
|
||||||
"{type=string, propertyName=passenger-nodejs, matchesRegEx=[^/], provided=[/usr/bin/node], defaultValue=/usr/bin/node}",
|
"{type=string, propertyName=passenger-nodejs, matchesRegEx=[^/.*], provided=[/usr/bin/node], defaultValue=/usr/bin/node}",
|
||||||
"{type=string, propertyName=passenger-python, matchesRegEx=[^/], provided=[/usr/bin/python3], defaultValue=/usr/bin/python3}",
|
"{type=string, propertyName=passenger-python, matchesRegEx=[^/.*], provided=[/usr/bin/python3], defaultValue=/usr/bin/python3}",
|
||||||
"{type=string, propertyName=passenger-ruby, matchesRegEx=[^/], provided=[/usr/bin/ruby], defaultValue=/usr/bin/ruby}",
|
"{type=string, propertyName=passenger-ruby, matchesRegEx=[^/.*], provided=[/usr/bin/ruby], defaultValue=/usr/bin/ruby}",
|
||||||
"{type=string[], propertyName=subdomains, elementsOf={type=string, propertyName=subdomains, matchesRegEx=[(?!-)[A-Za-z0-9-]{1,63}(?<!-)], required=true}}"
|
"{type=string[], propertyName=subdomains, elementsOf={type=string, propertyName=subdomains, matchesRegEx=[(?!-)[A-Za-z0-9-]{1,63}(?<!-)], required=true}}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -155,7 +156,7 @@ class HsDomainHttpSetupHostingAssetValidatorUnitTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(result).containsExactlyInAnyOrder(
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.htdocsfallback' is expected to be of type Boolean, but is of type String",
|
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.htdocsfallback' is expected to be of type Boolean, but is of type String",
|
||||||
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.fcgi-php-bin' is expected to match any of [^/] but 'false' does not match",
|
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.fcgi-php-bin' is expected to match any of [^/.*] but 'false' does not match",
|
||||||
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.subdomains' is expected to match any of [(?!-)[A-Za-z0-9-]{1,63}(?<!-)] but '' does not match",
|
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.subdomains' is expected to match any of [(?!-)[A-Za-z0-9-]{1,63}(?<!-)] but '' does not match",
|
||||||
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.subdomains' is expected to match any of [(?!-)[A-Za-z0-9-]{1,63}(?<!-)] but '@' does not match",
|
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.subdomains' is expected to match any of [(?!-)[A-Za-z0-9-]{1,63}(?<!-)] but '@' does not match",
|
||||||
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.subdomains' is expected to match any of [(?!-)[A-Za-z0-9-]{1,63}(?<!-)] but 'example.com' does not match");
|
"'DOMAIN_HTTP_SETUP:example.org|HTTP.config.subdomains' is expected to match any of [(?!-)[A-Za-z0-9-]{1,63}(?<!-)] but 'example.com' does not match");
|
||||||
|
@ -49,7 +49,7 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).containsExactly(
|
assertThat(result).containsExactly(
|
||||||
"'identifier' expected to match '^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}', but is '"+testCase.domainName+"'"
|
"'identifier' expected to match '^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,12}', but is '"+testCase.domainName+"'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,27 @@ class HsEMailAliasHostingAssetValidatorUnitTest {
|
|||||||
"'EMAIL_ALIAS:xyz00-office.config.target' is expected to match any of [^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9][a-z0-9\\._-]*)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$, ^:include:/.*$, ^\\|.*$, ^/dev/null$] but 'garbage' does not match any");
|
"'EMAIL_ALIAS:xyz00-office.config.target' is expected to match any of [^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9][a-z0-9\\._-]*)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$, ^:include:/.*$, ^\\|.*$, ^/dev/null$] but 'garbage' does not match any");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsEmptyTargetArray() {
|
||||||
|
// given
|
||||||
|
final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
|
.type(EMAIL_ALIAS)
|
||||||
|
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
||||||
|
.identifier("xyz00-office")
|
||||||
|
.config(Map.ofEntries(
|
||||||
|
entry("target", new String[0])
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(emailAliasHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(emailAliasHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
|
"'EMAIL_ALIAS:xyz00-office.config.target' length is expected to be at min 1 but length of [[]] is 0");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void rejectsInvalidIndentifier() {
|
void rejectsInvalidIndentifier() {
|
||||||
// given
|
// given
|
||||||
|
@ -11,6 +11,7 @@ import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
|||||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
import org.junit.jupiter.api.extension.TestWatcher;
|
import org.junit.jupiter.api.extension.TestWatcher;
|
||||||
|
import org.opentest4j.AssertionFailedError;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
@ -20,9 +21,9 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
@ -30,9 +31,9 @@ import java.io.StringWriter;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@ -40,7 +41,6 @@ import java.util.UUID;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
@ -77,7 +77,7 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
@MockBean
|
@MockBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
static final List<String> errors = new ArrayList<>();
|
static final LinkedHashSet<String> errors = new LinkedHashSet<>();
|
||||||
|
|
||||||
public List<String[]> readAllLines(Reader reader) throws Exception {
|
public List<String[]> readAllLines(Reader reader) throws Exception {
|
||||||
|
|
||||||
@ -115,7 +115,20 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Reader resourceReader(@NotNull final String resourcePath) {
|
protected Reader resourceReader(@NotNull final String resourcePath) {
|
||||||
return new InputStreamReader(requireNonNull(getClass().getClassLoader().getResourceAsStream(resourcePath)));
|
try {
|
||||||
|
return new InputStreamReader(requireNonNull(getClass().getClassLoader().getResourceAsStream(resourcePath)));
|
||||||
|
} catch (Exception exc) {
|
||||||
|
throw new AssertionFailedError("cannot open '" + resourcePath + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String resourceAsString(@NotNull final String resourcePath) {
|
||||||
|
try (InputStream inputStream = requireNonNull(getClass().getClassLoader().getResourceAsStream(resourcePath));
|
||||||
|
final var reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
|
||||||
|
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||||
|
} catch (Exception exc) {
|
||||||
|
throw new AssertionFailedError("cannot open '" + resourcePath + "'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String[]> withoutHeader(final List<String[]> records) {
|
protected List<String[]> withoutHeader(final List<String[]> records) {
|
||||||
@ -127,7 +140,9 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
try (final var reader = new CSVReader(new StringReader(csvLine))) {
|
try (final var reader = new CSVReader(new StringReader(csvLine))) {
|
||||||
return stream(ofNullable(reader.readNext()).orElse(emptyArray(String.class)))
|
return stream(ofNullable(reader.readNext()).orElse(emptyArray(String.class)))
|
||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.map(target -> target.startsWith("'") && target.endsWith("'") ? target.substring(1, target.length()-1) : target)
|
.map(target -> target.startsWith("'") && target.endsWith("'") ?
|
||||||
|
target.substring(1, target.length() - 1) :
|
||||||
|
target)
|
||||||
.toArray(String[]::new);
|
.toArray(String[]::new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +162,7 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (T) persistViaSql(id, ha);
|
return (T) persistViaSql(id, ha);
|
||||||
}
|
}
|
||||||
return persistViaEM(id, entity);
|
return persistViaEM(id, entity);
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
errors.add("failed to persist #" + entity.hashCode() + ": " + entity);
|
errors.add("failed to persist #" + entity.hashCode() + ": " + entity);
|
||||||
errors.add(exc.toString());
|
errors.add(exc.toString());
|
||||||
@ -171,38 +186,40 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final var query = em.createNativeQuery("""
|
final var query = em.createNativeQuery("""
|
||||||
insert into hs_hosting_asset(
|
insert into hs_hosting_asset(
|
||||||
uuid,
|
uuid,
|
||||||
type,
|
type,
|
||||||
bookingitemuuid,
|
bookingitemuuid,
|
||||||
parentassetuuid,
|
parentassetuuid,
|
||||||
assignedtoassetuuid,
|
assignedtoassetuuid,
|
||||||
alarmcontactuuid,
|
alarmcontactuuid,
|
||||||
identifier,
|
identifier,
|
||||||
caption,
|
caption,
|
||||||
config,
|
config,
|
||||||
version)
|
version)
|
||||||
values (
|
values (
|
||||||
:uuid,
|
:uuid,
|
||||||
:type,
|
:type,
|
||||||
:bookingitemuuid,
|
:bookingitemuuid,
|
||||||
:parentassetuuid,
|
:parentassetuuid,
|
||||||
:assignedtoassetuuid,
|
:assignedtoassetuuid,
|
||||||
:alarmcontactuuid,
|
:alarmcontactuuid,
|
||||||
:identifier,
|
:identifier,
|
||||||
:caption,
|
:caption,
|
||||||
cast(:config as jsonb),
|
cast(:config as jsonb),
|
||||||
:version)
|
:version)
|
||||||
""")
|
""")
|
||||||
.setParameter("uuid", entity.getUuid())
|
.setParameter("uuid", entity.getUuid())
|
||||||
.setParameter("type", entity.getType().name())
|
.setParameter("type", entity.getType().name())
|
||||||
.setParameter("bookingitemuuid", ofNullable(entity.getBookingItem()).map(BaseEntity::getUuid).orElse(null))
|
.setParameter("bookingitemuuid", ofNullable(entity.getBookingItem()).map(BaseEntity::getUuid).orElse(null))
|
||||||
.setParameter("parentassetuuid", ofNullable(entity.getParentAsset()).map(BaseEntity::getUuid).orElse(null))
|
.setParameter("parentassetuuid", ofNullable(entity.getParentAsset()).map(BaseEntity::getUuid).orElse(null))
|
||||||
.setParameter("assignedtoassetuuid", ofNullable(entity.getAssignedToAsset()).map(BaseEntity::getUuid).orElse(null))
|
.setParameter(
|
||||||
|
"assignedtoassetuuid",
|
||||||
|
ofNullable(entity.getAssignedToAsset()).map(BaseEntity::getUuid).orElse(null))
|
||||||
.setParameter("alarmcontactuuid", ofNullable(entity.getAlarmContact()).map(BaseEntity::getUuid).orElse(null))
|
.setParameter("alarmcontactuuid", ofNullable(entity.getAlarmContact()).map(BaseEntity::getUuid).orElse(null))
|
||||||
.setParameter("identifier", entity.getIdentifier())
|
.setParameter("identifier", entity.getIdentifier())
|
||||||
.setParameter("caption", entity.getCaption())
|
.setParameter("caption", entity.getCaption())
|
||||||
.setParameter("config", entity.getConfig().toString())
|
.setParameter("config", entity.getConfig().toString().replace("\t", "\\t"))
|
||||||
.setParameter("version", entity.getVersion());
|
.setParameter("version", entity.getVersion());
|
||||||
|
|
||||||
final var count = query.executeUpdate();
|
final var count = query.executeUpdate();
|
||||||
@ -212,17 +229,18 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <E> String toFormattedString(final Map<Integer, E> map) {
|
protected <E> String toJsonFormattedString(final Map<Integer, E> map) {
|
||||||
if ( map.isEmpty() ) {
|
if ( map.isEmpty() ) {
|
||||||
return "{}";
|
return "{}";
|
||||||
}
|
}
|
||||||
return "{\n" +
|
final var json = "{\n" +
|
||||||
map.keySet().stream()
|
map.keySet().stream()
|
||||||
.map(id -> " " + id + "=" + map.get(id).toString())
|
.map(id -> " " + id + "=" + map.get(id).toString())
|
||||||
.map(e -> e.replaceAll("\n ", " ").replace("\n", ""))
|
.map(e -> e.replaceAll("\n ", " ").replace("\n", "").replace(" : ", ": ").replace("{ ", "{").replace(", ", ", "))
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect(Collectors.joining(",\n")) +
|
.collect(Collectors.joining(",\n")) +
|
||||||
"\n}\n";
|
"\n}\n";
|
||||||
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void deleteTestDataFromHsOfficeTables() {
|
protected void deleteTestDataFromHsOfficeTables() {
|
||||||
@ -292,44 +310,26 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
try {
|
try {
|
||||||
assertion.run();
|
assertion.run();
|
||||||
} catch (final AssertionError exc) {
|
} catch (final AssertionError exc) {
|
||||||
errors.add(exc.toString());
|
logError(exc.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logErrors() {
|
public static void logError(final String error) {
|
||||||
final var errorsToLog = new ArrayList<>(errors);
|
errors.add(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void expectError(final String expectedError) {
|
||||||
|
final var found = errors.remove(expectedError);
|
||||||
|
if (!found) {
|
||||||
|
logError("expected but not found: " + expectedError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void assertNoErrors() {
|
||||||
|
final var errorsToLog = new LinkedHashSet<>(errors);
|
||||||
errors.clear();
|
errors.clear();
|
||||||
assertThat(errorsToLog).isEmpty();
|
assertThat(errorsToLog).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void expectErrors(final String... expectedErrors) {
|
|
||||||
assertContainsExactlyInAnyOrderIgnoringWhitespace(errors, expectedErrors);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class IgnoringWhitespaceComparator implements Comparator<String> {
|
|
||||||
@Override
|
|
||||||
public int compare(String s1, String s2) {
|
|
||||||
return s1.replaceAll("\\s", "").compareTo(s2.replaceAll("\\s", ""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void assertContainsExactlyInAnyOrderIgnoringWhitespace(final List<String> expected, final List<String> actual) {
|
|
||||||
final var sortedExpected = expected.stream()
|
|
||||||
.map(m -> m.replaceAll("\\s+", " "))
|
|
||||||
.map(m -> m.replaceAll("^ ", ""))
|
|
||||||
.map(m -> m.replaceAll(" $", ""))
|
|
||||||
.toList();
|
|
||||||
final var sortedActual = actual.stream()
|
|
||||||
.map(m -> m.replaceAll("\\s+", " "))
|
|
||||||
.map(m -> m.replaceAll("^ ", ""))
|
|
||||||
.map(m -> m.replaceAll(" $", ""))
|
|
||||||
.toArray(String[]::new);
|
|
||||||
assertThat(sortedExpected).containsExactlyInAnyOrder(sortedActual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void assertContainsExactlyInAnyOrderIgnoringWhitespace(final List<String> expected, final String... actual) {
|
|
||||||
assertContainsExactlyInAnyOrderIgnoringWhitespace(expected, asList(actual));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Columns {
|
class Columns {
|
||||||
@ -373,7 +373,7 @@ class Record {
|
|||||||
boolean getBoolean(final String columnName) {
|
boolean getBoolean(final String columnName) {
|
||||||
final String value = getString(columnName);
|
final String value = getString(columnName);
|
||||||
return isNotBlank(value) &&
|
return isNotBlank(value) &&
|
||||||
( parseBoolean(value.trim()) || value.trim().startsWith("t"));
|
(parseBoolean(value.trim()) || value.trim().startsWith("t"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer getInteger(final String columnName) {
|
Integer getInteger(final String columnName) {
|
||||||
@ -408,7 +408,9 @@ class OrderedDependedTestsExtension implements TestWatcher, BeforeEachCallback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void testFailed(final ExtensionContext context, final Throwable cause) {
|
public void testFailed(final ExtensionContext context, final Throwable cause) {
|
||||||
previousTestsPassed = previousTestsPassed && context.getElement().map(e -> e.isAnnotationPresent(ContinueOnFailure.class)).orElse(false);
|
previousTestsPassed = previousTestsPassed && context.getElement()
|
||||||
|
.map(e -> e.isAnnotationPresent(ContinueOnFailure.class))
|
||||||
|
.orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.migration;
|
package net.hostsharing.hsadminng.hs.migration;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hash.HashGenerator;
|
import net.hostsharing.hsadminng.hash.HashGenerator;
|
||||||
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
|
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
|
||||||
@ -10,6 +12,8 @@ import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityV
|
|||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry;
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
@ -18,12 +22,15 @@ import org.junit.jupiter.api.Tag;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.reflections.Reflections;
|
||||||
|
import org.reflections.scanners.ResourcesScanner;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.test.annotation.Commit;
|
import org.springframework.test.annotation.Commit;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.net.IDN;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -32,6 +39,8 @@ import java.util.TreeMap;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
@ -40,6 +49,11 @@ import static java.util.Optional.ofNullable;
|
|||||||
import static java.util.stream.Collectors.toMap;
|
import static java.util.stream.Collectors.toMap;
|
||||||
import static java.util.stream.Collectors.toSet;
|
import static java.util.stream.Collectors.toSet;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
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_HTTP_SETUP;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_MBOX_SETUP;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SMTP_SETUP;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ALIAS;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ALIAS;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.IPV4_NUMBER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.IPV4_NUMBER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
@ -112,6 +126,12 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
static final Integer DBINSTANCE_ID_OFFSET = 6000000;
|
static final Integer DBINSTANCE_ID_OFFSET = 6000000;
|
||||||
static final Integer DBUSER_ID_OFFSET = 7000000;
|
static final Integer DBUSER_ID_OFFSET = 7000000;
|
||||||
static final Integer DB_ID_OFFSET = 8000000;
|
static final Integer DB_ID_OFFSET = 8000000;
|
||||||
|
static final Integer DOMAIN_SETUP_OFFSET = 10000000;
|
||||||
|
static final Integer DOMAIN_DNS_SETUP_OFFSET = 11000000;
|
||||||
|
static final Integer DOMAIN_HTTP_SETUP_OFFSET = 12000000;
|
||||||
|
static final Integer DOMAIN_MBOX_SETUP_OFFSET = 13000000;
|
||||||
|
static final Integer DOMAIN_SMTP_SETUP_OFFSET = 14000000;
|
||||||
|
static List<String> zonefileErrors = new ArrayList<>();
|
||||||
|
|
||||||
record Hive(int hive_id, String hive_name, int inet_addr_id, AtomicReference<HsHostingAssetRealEntity> serverRef) {}
|
record Hive(int hive_id, String hive_name, int inet_addr_id, AtomicReference<HsHostingAssetRealEntity> serverRef) {}
|
||||||
|
|
||||||
@ -120,6 +140,9 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
static Map<Integer, Hive> hives = new WriteOnceMap<>();
|
static Map<Integer, Hive> hives = new WriteOnceMap<>();
|
||||||
static Map<Integer, HsHostingAssetRealEntity> hostingAssets = new WriteOnceMap<>(); // TODO.impl: separate maps for each type?
|
static Map<Integer, HsHostingAssetRealEntity> hostingAssets = new WriteOnceMap<>(); // TODO.impl: separate maps for each type?
|
||||||
static Map<String, HsHostingAssetRealEntity> dbUsersByEngineAndName = new WriteOnceMap<>();
|
static Map<String, HsHostingAssetRealEntity> dbUsersByEngineAndName = new WriteOnceMap<>();
|
||||||
|
static Map<String, HsHostingAssetRealEntity> domainSetupsByName = new WriteOnceMap<>();
|
||||||
|
|
||||||
|
final ObjectMapper jsonMapper = new ObjectMapper();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(11010)
|
@Order(11010)
|
||||||
@ -175,7 +198,7 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
void verifyHives() {
|
void verifyHives() {
|
||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
assertThat(toFormattedString(first(5, hives))).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(first(5, hives))).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
2000001=Hive[hive_id=1, hive_name=h00, inet_addr_id=358, serverRef=null],
|
2000001=Hive[hive_id=1, hive_name=h00, inet_addr_id=358, serverRef=null],
|
||||||
2000002=Hive[hive_id=2, hive_name=h01, inet_addr_id=359, serverRef=null],
|
2000002=Hive[hive_id=2, hive_name=h01, inet_addr_id=359, serverRef=null],
|
||||||
@ -267,15 +290,15 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
HsBookingItemType.MANAGED_WEBSPACE))
|
HsBookingItemType.MANAGED_WEBSPACE))
|
||||||
.isEqualToIgnoringWhitespace("""
|
.isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
3000630=HsBookingItemEntity(D-1000000:hsh default project, MANAGED_WEBSPACE, [2001-06-01,), BI hsh00, { "HDD": 10, "Multi": 25, "SLA-Platform": "EXT24H", "SSD": 16, "Traffic": 50}),
|
3000630=HsBookingItemEntity(D-1000000:hsh default project, MANAGED_WEBSPACE, [2001-06-01,), BI hsh00, {"HDD" : 10, "Multi" : 25, "SLA-Platform" : "EXT24H", "SSD" : 16, "Traffic" : 50}),
|
||||||
3000968=HsBookingItemEntity(D-1015200:rar default project, MANAGED_SERVER, [2013-04-01,), BI vm1061, { "CPU": 6, "HDD": 250, "RAM": 14, "SLA-EMail": true, "SLA-Maria": true, "SLA-Office": true, "SLA-PgSQL": true, "SLA-Platform": "EXT4H", "SLA-Web": true, "SSD": 375, "Traffic": 250}),
|
3000968=HsBookingItemEntity(D-1015200:rar default project, MANAGED_SERVER, [2013-04-01,), BI vm1061, {"CPU" : 6, "HDD" : 250, "RAM" : 14, "SLA-EMail" : true, "SLA-Maria" : true, "SLA-Office" : true, "SLA-PgSQL" : true, "SLA-Platform" : "EXT4H", "SLA-Web" : true, "SSD" : 375, "Traffic" : 250}),
|
||||||
3000978=HsBookingItemEntity(D-1000000:hsh default project, MANAGED_SERVER, [2013-04-01,), BI vm1050, { "CPU": 4, "HDD": 250, "RAM": 32, "SLA-EMail": true, "SLA-Maria": true, "SLA-Office": true, "SLA-PgSQL": true, "SLA-Platform": "EXT4H", "SLA-Web": true, "SSD": 150, "Traffic": 250}),
|
3000978=HsBookingItemEntity(D-1000000:hsh default project, MANAGED_SERVER, [2013-04-01,), BI vm1050, {"CPU" : 4, "HDD" : 250, "RAM" : 32, "SLA-EMail" : true, "SLA-Maria" : true, "SLA-Office" : true, "SLA-PgSQL" : true, "SLA-Platform" : "EXT4H", "SLA-Web" : true, "SSD" : 150, "Traffic" : 250}),
|
||||||
3001061=HsBookingItemEntity(D-1000300:mim default project, MANAGED_SERVER, [2013-08-19,), BI vm1068, { "CPU": 2, "HDD": 250, "RAM": 4, "SLA-EMail": true, "SLA-Maria": true, "SLA-Office": true, "SLA-PgSQL": true, "SLA-Platform": "EXT2H", "SLA-Web": true, "Traffic": 250}),
|
3001061=HsBookingItemEntity(D-1000300:mim default project, MANAGED_SERVER, [2013-08-19,), BI vm1068, {"CPU" : 2, "HDD" : 250, "RAM" : 4, "SLA-EMail" : true, "SLA-Maria" : true, "SLA-Office" : true, "SLA-PgSQL" : true, "SLA-Platform" : "EXT2H", "SLA-Web" : true, "Traffic" : 250}),
|
||||||
3001094=HsBookingItemEntity(D-1000300:mim default project, MANAGED_WEBSPACE, [2013-09-10,), BI lug00, { "Multi": 5, "SLA-Platform": "EXT24H", "SSD": 1, "Traffic": 10}),
|
3001094=HsBookingItemEntity(D-1000300:mim default project, MANAGED_WEBSPACE, [2013-09-10,), BI lug00, {"Multi" : 5, "SLA-Platform" : "EXT24H", "SSD" : 1, "Traffic" : 10}),
|
||||||
3001112=HsBookingItemEntity(D-1000300:mim default project, MANAGED_WEBSPACE, [2013-09-17,), BI mim00, { "Multi": 5, "SLA-Platform": "EXT24H", "SSD": 3, "Traffic": 20}),
|
3001112=HsBookingItemEntity(D-1000300:mim default project, MANAGED_WEBSPACE, [2013-09-17,), BI mim00, {"Multi" : 5, "SLA-Platform" : "EXT24H", "SSD" : 3, "Traffic" : 20}),
|
||||||
3001447=HsBookingItemEntity(D-1000000:hsh default project, MANAGED_SERVER, [2014-11-28,), BI vm1093, { "CPU": 6, "HDD": 500, "RAM": 16, "SLA-EMail": true, "SLA-Maria": true, "SLA-Office": true, "SLA-PgSQL": true, "SLA-Platform": "EXT4H", "SLA-Web": true, "SSD": 300, "Traffic": 250}),
|
3001447=HsBookingItemEntity(D-1000000:hsh default project, MANAGED_SERVER, [2014-11-28,), BI vm1093, {"CPU" : 6, "HDD" : 500, "RAM" : 16, "SLA-EMail" : true, "SLA-Maria" : true, "SLA-Office" : true, "SLA-PgSQL" : true, "SLA-Platform" : "EXT4H", "SLA-Web" : true, "SSD" : 300, "Traffic" : 250}),
|
||||||
3019959=HsBookingItemEntity(D-1101900:dph default project, MANAGED_WEBSPACE, [2021-06-02,), BI dph00, { "Multi": 1, "SLA-Platform": "EXT24H", "SSD": 25, "Traffic": 20}),
|
3019959=HsBookingItemEntity(D-1101900:dph default project, MANAGED_WEBSPACE, [2021-06-02,), BI dph00, {"Multi" : 1, "SLA-Platform" : "EXT24H", "SSD" : 25, "Traffic" : 20}),
|
||||||
3023611=HsBookingItemEntity(D-1101800:wws default project, CLOUD_SERVER, [2022-08-10,), BI vm2097, { "CPU": 8, "RAM": 12, "SLA-Infrastructure": "EXT4H", "SSD": 25, "Traffic": 250})
|
3023611=HsBookingItemEntity(D-1101800:wws default project, CLOUD_SERVER, [2022-08-10,), BI vm2097, {"CPU" : 8, "RAM" : 12, "SLA-Infrastructure" : "EXT4H", "SSD" : 25, "Traffic" : 250})
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -298,20 +321,20 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
|
|
||||||
assertThat(firstOfEachType(15, UNIX_USER)).isEqualToIgnoringWhitespace("""
|
assertThat(firstOfEachType(15, UNIX_USER)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
4005803=HsHostingAssetRealEntity(UNIX_USER, lug00, LUGs, MANAGED_WEBSPACE:lug00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102090}),
|
4005803=HsHostingAssetRealEntity(UNIX_USER, lug00, LUGs, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102090}),
|
||||||
4005805=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.1, Paul Klemm, MANAGED_WEBSPACE:lug00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102091}),
|
4005805=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.1, Paul Klemm, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102091}),
|
||||||
4005809=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.2, Walter Müller, MANAGED_WEBSPACE:lug00, { "SSD hard quota": 8, "SSD soft quota": 4, "locked": false, "shell": "/bin/bash", "userid": 102093}),
|
4005809=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.2, Walter Müller, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 8, "SSD soft quota": 4, "locked": false, "shell": "/bin/bash", "userid": 102093}),
|
||||||
4005811=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.a, LUG OLA - POP a, MANAGED_WEBSPACE:lug00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102094}),
|
4005811=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.a, LUG OLA - POP a, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102094}),
|
||||||
4005813=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.b, LUG OLA - POP b, MANAGED_WEBSPACE:lug00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102095}),
|
4005813=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.b, LUG OLA - POP b, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102095}),
|
||||||
4005835=HsHostingAssetRealEntity(UNIX_USER, lug00-test, Test, MANAGED_WEBSPACE:lug00, { "SSD hard quota": 1024, "SSD soft quota": 1024, "locked": false, "shell": "/usr/bin/passwd", "userid": 102106}),
|
4005835=HsHostingAssetRealEntity(UNIX_USER, lug00-test, Test, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 1024, "SSD soft quota": 1024, "locked": false, "shell": "/usr/bin/passwd", "userid": 102106}),
|
||||||
4005964=HsHostingAssetRealEntity(UNIX_USER, mim00, Michael Mellis, MANAGED_WEBSPACE:mim00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102147}),
|
4005964=HsHostingAssetRealEntity(UNIX_USER, mim00, Michael Mellis, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102147}),
|
||||||
4005966=HsHostingAssetRealEntity(UNIX_USER, mim00-1981, Jahrgangstreffen 1981, MANAGED_WEBSPACE:mim00, { "SSD hard quota": 256, "SSD soft quota": 128, "locked": false, "shell": "/bin/bash", "userid": 102148}),
|
4005966=HsHostingAssetRealEntity(UNIX_USER, mim00-1981, Jahrgangstreffen 1981, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 256, "SSD soft quota": 128, "locked": false, "shell": "/bin/bash", "userid": 102148}),
|
||||||
4005990=HsHostingAssetRealEntity(UNIX_USER, mim00-mail, Mailbox, MANAGED_WEBSPACE:mim00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102160}),
|
4005990=HsHostingAssetRealEntity(UNIX_USER, mim00-mail, Mailbox, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102160}),
|
||||||
4100705=HsHostingAssetRealEntity(UNIX_USER, hsh00-mim, Michael Mellis, MANAGED_WEBSPACE:hsh00, { "HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 10003}),
|
4100705=HsHostingAssetRealEntity(UNIX_USER, hsh00-mim, Michael Mellis, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 10003}),
|
||||||
4100824=HsHostingAssetRealEntity(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, { "HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 10000}),
|
4100824=HsHostingAssetRealEntity(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 10000}),
|
||||||
4167846=HsHostingAssetRealEntity(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, { "HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 110568}),
|
4167846=HsHostingAssetRealEntity(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 110568}),
|
||||||
4169546=HsHostingAssetRealEntity(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110593}),
|
4169546=HsHostingAssetRealEntity(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110593}),
|
||||||
4169596=HsHostingAssetRealEntity(UNIX_USER, dph00-uph, Domain admin, MANAGED_WEBSPACE:dph00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110594})
|
4169596=HsHostingAssetRealEntity(UNIX_USER, dph00-dph, Domain admin, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110594})
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -334,17 +357,15 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
|
|
||||||
assertThat(firstOfEachType(15, EMAIL_ALIAS)).isEqualToIgnoringWhitespace("""
|
assertThat(firstOfEachType(15, EMAIL_ALIAS)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
5002403=HsHostingAssetRealEntity(EMAIL_ALIAS, lug00, lug00, MANAGED_WEBSPACE:lug00, { "target": "[michael.mellis@example.com]"}),
|
5002403=HsHostingAssetRealEntity(EMAIL_ALIAS, lug00, lug00, MANAGED_WEBSPACE:lug00, {"target": [ "michael.mellis@example.com" ]}),
|
||||||
5002405=HsHostingAssetRealEntity(EMAIL_ALIAS, lug00-wla-listar, lug00-wla-listar, MANAGED_WEBSPACE:lug00, { "target": "[|/home/pacs/lug00/users/in/mailinglist/listar]"}),
|
5002405=HsHostingAssetRealEntity(EMAIL_ALIAS, lug00-wla-listar, lug00-wla-listar, MANAGED_WEBSPACE:lug00, {"target": [ "|/home/pacs/lug00/users/in/mailinglist/listar" ]}),
|
||||||
5002429=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00, mim00, MANAGED_WEBSPACE:mim00, { "target": "[mim12-mi@mim12.hostsharing.net]"}),
|
5002429=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00, mim00, MANAGED_WEBSPACE:mim00, {"target": [ "mim12-mi@mim12.hostsharing.net" ]}),
|
||||||
5002431=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-abruf, mim00-abruf, MANAGED_WEBSPACE:mim00, { "target": "[michael.mellis@hostsharing.net]"}),
|
5002431=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-abruf, mim00-abruf, MANAGED_WEBSPACE:mim00, {"target": [ "michael.mellis@hostsharing.net" ]}),
|
||||||
5002449=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-hhfx, mim00-hhfx, MANAGED_WEBSPACE:mim00, { "target": "[mim00-hhfx, |/usr/bin/formail -I 'Reply-To: hamburger-fx@example.net' | /usr/lib/sendmail mim00-hhfx-l]"}),
|
5002449=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-hhfx, mim00-hhfx, MANAGED_WEBSPACE:mim00, {"target": [ "mim00-hhfx", "|/usr/bin/formail -I 'Reply-To: hamburger-fx@example.net' | /usr/lib/sendmail mim00-hhfx-l" ]}),
|
||||||
5002451=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-hhfx-l, mim00-hhfx-l, MANAGED_WEBSPACE:mim00, { "target": "[:include:/home/pacs/mim00/etc/hhfx.list]"}),
|
5002451=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-hhfx-l, mim00-hhfx-l, MANAGED_WEBSPACE:mim00, {"target": [ ":include:/home/pacs/mim00/etc/hhfx.list" ]}),
|
||||||
5002452=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-empty, mim00-empty, MANAGED_WEBSPACE:mim00, { "target": "[]"}),
|
5002454=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-dev.null, mim00-dev.null, MANAGED_WEBSPACE:mim00, {"target": [ "/dev/null" ]}),
|
||||||
5002453=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-0_entries, mim00-0_entries, MANAGED_WEBSPACE:mim00, { "target": "[]"}),
|
5002455=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-1_with_space, mim00-1_with_space, MANAGED_WEBSPACE:mim00, {"target": [ "|/home/pacs/mim00/install/corpslistar/listar" ]}),
|
||||||
5002454=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-dev.null, mim00-dev.null, MANAGED_WEBSPACE:mim00, { "target": "[/dev/null]"}),
|
5002456=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-1_with_single_quotes, mim00-1_with_single_quotes, MANAGED_WEBSPACE:mim00, {"target": [ "|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern" ]})
|
||||||
5002455=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-1_with_space, mim00-1_with_space, MANAGED_WEBSPACE:mim00, { "target": "[|/home/pacs/mim00/install/corpslistar/listar]"}),
|
|
||||||
5002456=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-1_with_single_quotes, mim00-1_with_single_quotes, MANAGED_WEBSPACE:mim00, { "target": "[|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern]"})
|
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -352,7 +373,7 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
@Test
|
@Test
|
||||||
@Order(15000)
|
@Order(15000)
|
||||||
void createDatabaseInstances() {
|
void createDatabaseInstances() {
|
||||||
createDatabaseInstances(hostingAssets.values().stream().filter(ha -> ha.getType()==MANAGED_SERVER).toList());
|
createDatabaseInstances(hostingAssets.values().stream().filter(ha -> ha.getType() == MANAGED_SERVER).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -438,6 +459,94 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(16010)
|
||||||
|
void importDomains() {
|
||||||
|
try (Reader reader = resourceReader(MIGRATION_DATA_PATH + "/hosting/domain.csv")) {
|
||||||
|
final var lines = readAllLines(reader);
|
||||||
|
importDomains(justHeader(lines), withoutHeader(lines));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(16020)
|
||||||
|
void importZonenfiles() {
|
||||||
|
final var reflections = new Reflections(MIGRATION_DATA_PATH + "/hosting/zonefiles", new ResourcesScanner());
|
||||||
|
final var zonefileFiles = reflections.getResources(Pattern.compile(".*\\.json")).stream().sorted().toList();
|
||||||
|
zonefileFiles.forEach(zonenfileName -> {
|
||||||
|
System.out.println("Processing zonenfile: " + zonenfileName);
|
||||||
|
importZonefiles(vmName(zonenfileName), resourceAsString(zonenfileName));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private String vmName(final String zonenfileName) {
|
||||||
|
return zonenfileName.substring(zonenfileName.length() - "vm0000.json".length()).substring(0, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(16019)
|
||||||
|
void verifyDomains() {
|
||||||
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
|
assertThat(firstOfEachType(
|
||||||
|
12,
|
||||||
|
DOMAIN_SETUP,
|
||||||
|
DOMAIN_DNS_SETUP,
|
||||||
|
DOMAIN_HTTP_SETUP,
|
||||||
|
DOMAIN_MBOX_SETUP,
|
||||||
|
DOMAIN_SMTP_SETUP)).isEqualToIgnoringWhitespace("""
|
||||||
|
{
|
||||||
|
10004531=HsHostingAssetRealEntity(DOMAIN_SETUP, l-u-g.org, l-u-g.org),
|
||||||
|
10004532=HsHostingAssetRealEntity(DOMAIN_SETUP, linuxfanboysngirls.de, linuxfanboysngirls.de),
|
||||||
|
10004534=HsHostingAssetRealEntity(DOMAIN_SETUP, lug-mars.de, lug-mars.de),
|
||||||
|
10004581=HsHostingAssetRealEntity(DOMAIN_SETUP, 1981.ist-im-netz.de, 1981.ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de),
|
||||||
|
10004587=HsHostingAssetRealEntity(DOMAIN_SETUP, mellis.de, mellis.de),
|
||||||
|
10004589=HsHostingAssetRealEntity(DOMAIN_SETUP, ist-im-netz.de, ist-im-netz.de),
|
||||||
|
10004600=HsHostingAssetRealEntity(DOMAIN_SETUP, waera.de, waera.de),
|
||||||
|
10004604=HsHostingAssetRealEntity(DOMAIN_SETUP, xn--wra-qla.de, wära.de),
|
||||||
|
10027662=HsHostingAssetRealEntity(DOMAIN_SETUP, dph-netzwerk.de, dph-netzwerk.de),
|
||||||
|
11004531=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, l-u-g.org|DNS, DNS-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00),
|
||||||
|
11004532=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, linuxfanboysngirls.de|DNS, DNS-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00),
|
||||||
|
11004534=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, lug-mars.de|DNS, DNS-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00),
|
||||||
|
11004581=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, 1981.ist-im-netz.de|DNS, DNS-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
11004587=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, mellis.de|DNS, DNS-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
11004589=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, ist-im-netz.de|DNS, DNS-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
11004600=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, waera.de|DNS, DNS-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
11004604=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, xn--wra-qla.de|DNS, DNS-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
11027662=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, dph-netzwerk.de|DNS, DNS-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00),
|
||||||
|
12004531=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, l-u-g.org|HTTP, HTTP-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, UNIX_USER:lug00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
|
||||||
|
12004532=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, linuxfanboysngirls.de|HTTP, HTTP-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, UNIX_USER:lug00-wla.2, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
|
||||||
|
12004534=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, lug-mars.de|HTTP, HTTP-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, UNIX_USER:lug00-wla.2, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "www" ]}),
|
||||||
|
12004581=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, 1981.ist-im-netz.de|HTTP, HTTP-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
|
||||||
|
12004587=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, mellis.de|HTTP, HTTP-Setup für mellis.de, DOMAIN_SETUP:mellis.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": false, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "www", "michael", "test", "photos", "static", "input" ]}),
|
||||||
|
12004589=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, ist-im-netz.de|HTTP, HTTP-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": false, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
|
||||||
|
12004600=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, waera.de|HTTP, HTTP-Setup für waera.de, DOMAIN_SETUP:waera.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
|
||||||
|
12004604=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, xn--wra-qla.de|HTTP, HTTP-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
|
||||||
|
12027662=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, dph-netzwerk.de|HTTP, HTTP-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, UNIX_USER:dph00-dph, {"autoconfig": true, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
|
||||||
|
13004531=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, l-u-g.org|MBOX, E-Mail-Empfang-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00),
|
||||||
|
13004532=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, linuxfanboysngirls.de|MBOX, E-Mail-Empfang-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00),
|
||||||
|
13004534=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, lug-mars.de|MBOX, E-Mail-Empfang-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00),
|
||||||
|
13004581=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, 1981.ist-im-netz.de|MBOX, E-Mail-Empfang-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
13004587=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, mellis.de|MBOX, E-Mail-Empfang-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
13004589=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, ist-im-netz.de|MBOX, E-Mail-Empfang-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
13004600=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, waera.de|MBOX, E-Mail-Empfang-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
13004604=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, xn--wra-qla.de|MBOX, E-Mail-Empfang-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
13027662=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, dph-netzwerk.de|MBOX, E-Mail-Empfang-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00),
|
||||||
|
14004531=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, l-u-g.org|SMTP, E-Mail-Versand-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00),
|
||||||
|
14004532=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, linuxfanboysngirls.de|SMTP, E-Mail-Versand-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00),
|
||||||
|
14004534=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, lug-mars.de|SMTP, E-Mail-Versand-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00),
|
||||||
|
14004581=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, 1981.ist-im-netz.de|SMTP, E-Mail-Versand-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
14004587=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, mellis.de|SMTP, E-Mail-Versand-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
14004589=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, ist-im-netz.de|SMTP, E-Mail-Versand-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
14004600=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, waera.de|SMTP, E-Mail-Versand-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
14004604=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, xn--wra-qla.de|SMTP, E-Mail-Versand-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00),
|
||||||
|
14027662=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, dph-netzwerk.de|SMTP, E-Mail-Versand-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00)
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -471,7 +580,11 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
@Order(18999)
|
@Order(18999)
|
||||||
@ContinueOnFailure
|
@ContinueOnFailure
|
||||||
void logValidationErrors() {
|
void logValidationErrors() {
|
||||||
this.logErrors();
|
if (isImportingControlledTestData()) {
|
||||||
|
expectError("zonedata dom_owner of mellis.de is old00 but expected to be mim00");
|
||||||
|
expectError("\nexpected: \"vm1068\"\n but was: \"vm1093\"");
|
||||||
|
}
|
||||||
|
this.assertNoErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
@ -576,6 +689,46 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
persistHostingAssetsOfType(PGSQL_DATABASE, MARIADB_DATABASE);
|
persistHostingAssetsOfType(PGSQL_DATABASE, MARIADB_DATABASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(19300)
|
||||||
|
@Commit
|
||||||
|
void persistDomainSetups() {
|
||||||
|
System.out.println("PERSISTING domain setups to database '" + jdbcUrl + "' as user '" + postgresAdminUser + "'");
|
||||||
|
persistHostingAssetsOfType(DOMAIN_SETUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(19301)
|
||||||
|
@Commit
|
||||||
|
void persistDomainDnsSetups() {
|
||||||
|
System.out.println("PERSISTING domain DNS setups to database '" + jdbcUrl + "' as user '" + postgresAdminUser + "'");
|
||||||
|
persistHostingAssetsOfType(DOMAIN_DNS_SETUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(19302)
|
||||||
|
@Commit
|
||||||
|
void persistDomainHttpSetups() {
|
||||||
|
System.out.println("PERSISTING domain HTTP setups to database '" + jdbcUrl + "' as user '" + postgresAdminUser + "'");
|
||||||
|
persistHostingAssetsOfType(DOMAIN_HTTP_SETUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(19303)
|
||||||
|
@Commit
|
||||||
|
void persistDomainMboxSetups() {
|
||||||
|
System.out.println("PERSISTING domain MBOX setups to database '" + jdbcUrl + "' as user '" + postgresAdminUser + "'");
|
||||||
|
persistHostingAssetsOfType(DOMAIN_MBOX_SETUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(19304)
|
||||||
|
@Commit
|
||||||
|
void persistDomainSmtpSetups() {
|
||||||
|
System.out.println("PERSISTING domain SMTP setups to database '" + jdbcUrl + "' as user '" + postgresAdminUser + "'");
|
||||||
|
persistHostingAssetsOfType(DOMAIN_SMTP_SETUP);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(19900)
|
@Order(19900)
|
||||||
void verifyPersistedUnixUsersWithUserId() {
|
void verifyPersistedUnixUsersWithUserId() {
|
||||||
@ -596,7 +749,7 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
4100824=HsHostingAssetRealEntity(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, { "HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 10000}),
|
4100824=HsHostingAssetRealEntity(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, { "HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 10000}),
|
||||||
4167846=HsHostingAssetRealEntity(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, { "HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/false", "userid": 110568}),
|
4167846=HsHostingAssetRealEntity(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, { "HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/false", "userid": 110568}),
|
||||||
4169546=HsHostingAssetRealEntity(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110593}),
|
4169546=HsHostingAssetRealEntity(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110593}),
|
||||||
4169596=HsHostingAssetRealEntity(UNIX_USER, dph00-uph, Domain admin, MANAGED_WEBSPACE:dph00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110594})
|
4169596=HsHostingAssetRealEntity(UNIX_USER, dph00-dph, Domain admin, MANAGED_WEBSPACE:dph00, { "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110594})
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -604,37 +757,26 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
@Test
|
@Test
|
||||||
@Order(19910)
|
@Order(19910)
|
||||||
void verifyBookingItemsAreActuallyPersisted() {
|
void verifyBookingItemsAreActuallyPersisted() {
|
||||||
final var biCount = (Integer) em.createNativeQuery("SELECT count(*) FROM hs_booking_item", Integer.class).getSingleResult();
|
final var biCount = (Integer) em.createNativeQuery("select count(*) from hs_booking_item", Integer.class)
|
||||||
|
.getSingleResult();
|
||||||
assertThat(biCount).isGreaterThan(isImportingControlledTestData() ? 5 : 500);
|
assertThat(biCount).isGreaterThan(isImportingControlledTestData() ? 5 : 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(19920)
|
@Order(19920)
|
||||||
void verifyHostingAssetsAreActuallyPersisted() {
|
void verifyHostingAssetsAreActuallyPersisted() {
|
||||||
final var haCount = (Integer) em.createNativeQuery("SELECT count(*) FROM hs_hosting_asset", Integer.class).getSingleResult();
|
final var haCount = (Integer) em.createNativeQuery("select count(*) from hs_hosting_asset", Integer.class)
|
||||||
assertThat(haCount).isGreaterThan(isImportingControlledTestData() ? 30 : 10000);
|
.getSingleResult();
|
||||||
|
assertThat(haCount).isGreaterThan(isImportingControlledTestData() ? 40 : 15000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================================
|
// ============================================================================================
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(99999)
|
@Order(19999)
|
||||||
void logErrors() {
|
void logErrorsAfterPersistingHostingAssets() {
|
||||||
if (isImportingControlledTestData()) {
|
errors.addAll(zonefileErrors);
|
||||||
super.expectErrors("""
|
assertNoErrors();
|
||||||
validation failed for id:5002452( HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-empty, mim00-empty, MANAGED_WEBSPACE:mim00, {
|
|
||||||
"target": "[]"
|
|
||||||
}
|
|
||||||
)): ['EMAIL_ALIAS:mim00-empty.config.target' length is expected to be at min 1 but length of [[]] is 0]""",
|
|
||||||
"""
|
|
||||||
validation failed for id:5002453( HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-0_entries, mim00-0_entries, MANAGED_WEBSPACE:mim00, {
|
|
||||||
"target": "[]"
|
|
||||||
}
|
|
||||||
)): ['EMAIL_ALIAS:mim00-0_entries.config.target' length is expected to be at min 1 but length of [[]] is 0]"""
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
super.logErrors();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void persistRecursively(final Integer key, final HsBookingItemEntity bi) {
|
private void persistRecursively(final Integer key, final HsBookingItemEntity bi) {
|
||||||
@ -648,20 +790,26 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
|
|
||||||
private void persistHostingAssetsOfType(final HsHostingAssetType... hsHostingAssetTypes) {
|
private void persistHostingAssetsOfType(final HsHostingAssetType... hsHostingAssetTypes) {
|
||||||
final var hsHostingAssetTypeSet = stream(hsHostingAssetTypes).collect(toSet());
|
final var hsHostingAssetTypeSet = stream(hsHostingAssetTypes).collect(toSet());
|
||||||
jpaAttempt.transacted(() -> {
|
|
||||||
hostingAssets.forEach((key, ha) -> {
|
if (hsHostingAssetTypeSet.contains(DOMAIN_DNS_SETUP)) {
|
||||||
context(rbacSuperuser);
|
HsDomainDnsSetupHostingAssetValidator.addZonefileErrorsTo(zonefileErrors);
|
||||||
if (hsHostingAssetTypeSet.contains(ha.getType())) {
|
}
|
||||||
new HostingAssetEntitySaveProcessor(em, ha)
|
|
||||||
.preprocessEntity()
|
jpaAttempt.transacted(() ->
|
||||||
.validateEntityIgnoring("'EMAIL_ALIAS:.*\\.config\\.target' .*")
|
hostingAssets.forEach((key, ha) -> {
|
||||||
.prepareForSave()
|
if (hsHostingAssetTypeSet.contains(ha.getType())) {
|
||||||
.saveUsing(entity -> persist(key, entity))
|
context(rbacSuperuser); // if put only outside the loop, it seems to get lost after a while, no idea why
|
||||||
.validateContext();
|
logError(() ->
|
||||||
}
|
new HostingAssetEntitySaveProcessor(em, ha)
|
||||||
|
.preprocessEntity()
|
||||||
|
.validateEntityIgnoring("'EMAIL_ALIAS:.*\\.config\\.target' .*")
|
||||||
|
.prepareForSave()
|
||||||
|
.saveUsing(entity -> persist(key, entity))
|
||||||
|
.validateContext()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
})
|
||||||
}).assertSuccessful();
|
).assertSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importIpNumbers(final String[] header, final List<String[]> records) {
|
private void importIpNumbers(final String[] header, final List<String[]> records) {
|
||||||
@ -894,12 +1042,14 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
|
|
||||||
// TODO.spec: crop SSD+HDD limits if > booked
|
// TODO.spec: crop SSD+HDD limits if > booked
|
||||||
if (unixUserAsset.getDirectValue("SSD hard quota", Integer.class, 0)
|
if (unixUserAsset.getDirectValue("SSD hard quota", Integer.class, 0)
|
||||||
> 1024*unixUserAsset.getContextValue("SSD", Integer.class, 0)) {
|
> 1024 * unixUserAsset.getContextValue("SSD", Integer.class, 0)) {
|
||||||
unixUserAsset.getConfig().put("SSD hard quota", unixUserAsset.getContextValue("SSD", Integer.class, 0)*1024);
|
unixUserAsset.getConfig()
|
||||||
|
.put("SSD hard quota", unixUserAsset.getContextValue("SSD", Integer.class, 0) * 1024);
|
||||||
}
|
}
|
||||||
if (unixUserAsset.getDirectValue("HDD hard quota", Integer.class, 0)
|
if (unixUserAsset.getDirectValue("HDD hard quota", Integer.class, 0)
|
||||||
> 1024*unixUserAsset.getContextValue("HDD", Integer.class, 0)) {
|
> 1024 * unixUserAsset.getContextValue("HDD", Integer.class, 0)) {
|
||||||
unixUserAsset.getConfig().put("HDD hard quota", unixUserAsset.getContextValue("HDD", Integer.class, 0)*1024);
|
unixUserAsset.getConfig()
|
||||||
|
.put("HDD hard quota", unixUserAsset.getContextValue("HDD", Integer.class, 0) * 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO.spec: does `softlimit<hardlimit?` even make sense? Fix it in this or the other direction?
|
// TODO.spec: does `softlimit<hardlimit?` even make sense? Fix it in this or the other direction?
|
||||||
@ -986,7 +1136,9 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
: failWith("unknown DB engine " + engine);
|
: failWith("unknown DB engine " + engine);
|
||||||
final var hash = dbUserAssetType == MARIADB_USER ? Algorithm.MYSQL_NATIVE : Algorithm.SCRAM_SHA256;
|
final var hash = dbUserAssetType == MARIADB_USER ? Algorithm.MYSQL_NATIVE : Algorithm.SCRAM_SHA256;
|
||||||
final var name = rec.getString("name");
|
final var name = rec.getString("name");
|
||||||
final var password_hash = rec.getString("password_hash", HashGenerator.using(hash).withRandomSalt().hash("fake pw " + name));
|
final var password_hash = rec.getString(
|
||||||
|
"password_hash",
|
||||||
|
HashGenerator.using(hash).withRandomSalt().hash("fake pw " + name));
|
||||||
|
|
||||||
final HsHostingAssetType dbInstanceAssetType = "mysql".equals(engine) ? MARIADB_INSTANCE
|
final HsHostingAssetType dbInstanceAssetType = "mysql".equals(engine) ? MARIADB_INSTANCE
|
||||||
: "pgsql".equals(engine) ? PGSQL_INSTANCE
|
: "pgsql".equals(engine) ? PGSQL_INSTANCE
|
||||||
@ -1020,7 +1172,7 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
final var database_id = rec.getInteger("database_id");
|
final var database_id = rec.getInteger("database_id");
|
||||||
final var engine = rec.getString("engine");
|
final var engine = rec.getString("engine");
|
||||||
final var owner = rec.getString("owner");
|
final var owner = rec.getString("owner");
|
||||||
final var owningDbUserHA = dbUsersByEngineAndName.get(engine + ":" + owner);
|
final var owningDbUserHA = dbUsersByEngineAndName.get(engine + ":" + owner);
|
||||||
assertThat(owningDbUserHA).as("owning user for " + (engine + ":" + owner) + " not found").isNotNull();
|
assertThat(owningDbUserHA).as("owning user for " + (engine + ":" + owner) + " not found").isNotNull();
|
||||||
final HsHostingAssetType type = "mysql".equals(engine) ? MARIADB_DATABASE
|
final HsHostingAssetType type = "mysql".equals(engine) ? MARIADB_DATABASE
|
||||||
: "pgsql".equals(engine) ? PGSQL_DATABASE
|
: "pgsql".equals(engine) ? PGSQL_DATABASE
|
||||||
@ -1033,13 +1185,191 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
.identifier(type.name().substring(0, 2) + "D|" + name)
|
.identifier(type.name().substring(0, 2) + "D|" + name)
|
||||||
.caption(name)
|
.caption(name)
|
||||||
.config(ofEntries(
|
.config(ofEntries(
|
||||||
entry("encoding", type == MARIADB_DATABASE ? encoding.toLowerCase() : encoding.toUpperCase())
|
entry(
|
||||||
|
"encoding",
|
||||||
|
type == MARIADB_DATABASE ? encoding.toLowerCase() : encoding.toUpperCase())
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
hostingAssets.put(DB_ID_OFFSET + database_id, dbAsset);
|
hostingAssets.put(DB_ID_OFFSET + database_id, dbAsset);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void importDomains(final String[] header, final List<String[]> records) {
|
||||||
|
final var httpDomainSetupValidator = HostingAssetEntityValidatorRegistry.forType(DOMAIN_HTTP_SETUP);
|
||||||
|
|
||||||
|
final var columns = new Columns(header);
|
||||||
|
records.stream()
|
||||||
|
.map(this::trimAll)
|
||||||
|
.map(row -> new Record(columns, row))
|
||||||
|
.forEach(rec -> {
|
||||||
|
final var domain_id = rec.getInteger("domain_id");
|
||||||
|
final var domain_name = rec.getString("domain_name");
|
||||||
|
// final var domain_since = rec.getString("domain_since");
|
||||||
|
// final var domain_dns_master = rec.getString("domain_dns_master");
|
||||||
|
final var owner_id = rec.getInteger("domain_owner");
|
||||||
|
final var domainoptions = rec.getString("domainoptions");
|
||||||
|
|
||||||
|
// Domain Setup
|
||||||
|
final var domainSetupAsset = HsHostingAssetRealEntity.builder()
|
||||||
|
.type(DOMAIN_SETUP)
|
||||||
|
// .parentAsset(parentDomainSetupAsset) are set once we've collected all of them
|
||||||
|
.identifier(domain_name)
|
||||||
|
.caption(IDN.toUnicode(domain_name))
|
||||||
|
.config(ofEntries(
|
||||||
|
// nothing here
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
domainSetupsByName.put(domain_name, domainSetupAsset);
|
||||||
|
hostingAssets.put(DOMAIN_SETUP_OFFSET + domain_id, domainSetupAsset);
|
||||||
|
domainSetupAsset.setSubHostingAssets(new ArrayList<>());
|
||||||
|
|
||||||
|
// Domain DNS Setup
|
||||||
|
final var ownerAsset = hostingAssets.get(UNIXUSER_ID_OFFSET + owner_id);
|
||||||
|
final var webspaceAsset = ownerAsset.getParentAsset();
|
||||||
|
assertThat(webspaceAsset.getType()).isEqualTo(MANAGED_WEBSPACE);
|
||||||
|
final var domainDnsSetupAsset = HsHostingAssetRealEntity.builder()
|
||||||
|
.type(DOMAIN_DNS_SETUP)
|
||||||
|
.parentAsset(domainSetupAsset)
|
||||||
|
.assignedToAsset(webspaceAsset)
|
||||||
|
.identifier(domain_name + "|DNS")
|
||||||
|
.caption("DNS-Setup für " + IDN.toUnicode(domain_name))
|
||||||
|
.config(new HashMap<>()) // is read from separate files
|
||||||
|
.build();
|
||||||
|
hostingAssets.put(DOMAIN_DNS_SETUP_OFFSET + domain_id, domainDnsSetupAsset);
|
||||||
|
domainSetupAsset.getSubHostingAssets().add(domainDnsSetupAsset);
|
||||||
|
|
||||||
|
// Domain HTTP Setup
|
||||||
|
final var options = stream(domainoptions.split(",")).collect(toSet());
|
||||||
|
final var domainHttpSetupAsset = HsHostingAssetRealEntity.builder()
|
||||||
|
.type(DOMAIN_HTTP_SETUP)
|
||||||
|
.parentAsset(domainSetupAsset)
|
||||||
|
.assignedToAsset(ownerAsset)
|
||||||
|
.identifier(domain_name + "|HTTP")
|
||||||
|
.caption("HTTP-Setup für " + IDN.toUnicode(domain_name))
|
||||||
|
.config(ofEntries(
|
||||||
|
entry("htdocsfallback", options.contains("htdocsfallback")),
|
||||||
|
entry("indexes", options.contains("indexes")),
|
||||||
|
entry("cgi", options.contains("cgi")),
|
||||||
|
entry("passenger", options.contains("passenger")),
|
||||||
|
entry("passenger-errorpage", options.contains("passenger-errorpage")),
|
||||||
|
entry("fastcgi", options.contains("fastcgi")),
|
||||||
|
entry("autoconfig", options.contains("autoconfig")),
|
||||||
|
entry("greylisting", options.contains("greylisting")),
|
||||||
|
entry("includes", options.contains("includes")),
|
||||||
|
entry("letsencrypt", options.contains("letsencrypt")),
|
||||||
|
entry("multiviews", options.contains("multiviews")),
|
||||||
|
entry("subdomains", withDefault(rec.getString("valid_subdomain_names"), "*")
|
||||||
|
.split(",")),
|
||||||
|
entry("fcgi-php-bin", withDefault(
|
||||||
|
rec.getString("fcgi_php_bin"),
|
||||||
|
httpDomainSetupValidator.getProperty("fcgi-php-bin").defaultValue())),
|
||||||
|
entry("passenger-nodejs", withDefault(
|
||||||
|
rec.getString("passenger_nodejs"),
|
||||||
|
httpDomainSetupValidator.getProperty("passenger-nodejs").defaultValue())),
|
||||||
|
entry("passenger-python", withDefault(
|
||||||
|
rec.getString("passenger_python"),
|
||||||
|
httpDomainSetupValidator.getProperty("passenger-python").defaultValue())),
|
||||||
|
entry("passenger-ruby", withDefault(
|
||||||
|
rec.getString("passenger_ruby"),
|
||||||
|
httpDomainSetupValidator.getProperty("passenger-ruby").defaultValue()))
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
hostingAssets.put(DOMAIN_HTTP_SETUP_OFFSET + domain_id, domainHttpSetupAsset);
|
||||||
|
domainSetupAsset.getSubHostingAssets().add(domainHttpSetupAsset);
|
||||||
|
|
||||||
|
// Domain MBOX Setup
|
||||||
|
final var domainMboxSetupAsset = HsHostingAssetRealEntity.builder()
|
||||||
|
.type(DOMAIN_MBOX_SETUP)
|
||||||
|
.parentAsset(domainSetupAsset)
|
||||||
|
.assignedToAsset(webspaceAsset)
|
||||||
|
.identifier(domain_name + "|MBOX")
|
||||||
|
.caption("E-Mail-Empfang-Setup für " + IDN.toUnicode(domain_name))
|
||||||
|
.config(ofEntries(
|
||||||
|
// no properties available
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
hostingAssets.put(DOMAIN_MBOX_SETUP_OFFSET + domain_id, domainMboxSetupAsset);
|
||||||
|
domainSetupAsset.getSubHostingAssets().add(domainMboxSetupAsset);
|
||||||
|
|
||||||
|
// Domain SMTP Setup
|
||||||
|
final var domainSmtpSetupAsset = HsHostingAssetRealEntity.builder()
|
||||||
|
.type(DOMAIN_SMTP_SETUP)
|
||||||
|
.parentAsset(domainSetupAsset)
|
||||||
|
.assignedToAsset(webspaceAsset)
|
||||||
|
.identifier(domain_name + "|SMTP")
|
||||||
|
.caption("E-Mail-Versand-Setup für " + IDN.toUnicode(domain_name))
|
||||||
|
.config(ofEntries(
|
||||||
|
// no properties available
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
hostingAssets.put(DOMAIN_SMTP_SETUP_OFFSET + domain_id, domainSmtpSetupAsset);
|
||||||
|
domainSetupAsset.getSubHostingAssets().add(domainSmtpSetupAsset);
|
||||||
|
});
|
||||||
|
|
||||||
|
domainSetupsByName.values().forEach(domainSetup -> {
|
||||||
|
final var parentDomainName = domainSetup.getIdentifier().split("\\.", 2)[1];
|
||||||
|
final var parentDomainSetup = domainSetupsByName.get(parentDomainName);
|
||||||
|
if (parentDomainSetup != null) {
|
||||||
|
domainSetup.setParentAsset(parentDomainSetup);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private String withDefault(final String givenValue, final Object defaultValue) {
|
||||||
|
if (defaultValue instanceof String defaultStringValue) {
|
||||||
|
return givenValue != null && !givenValue.isBlank() ? givenValue : defaultStringValue;
|
||||||
|
}
|
||||||
|
throw new RuntimeException(
|
||||||
|
"property default value expected to be of type string, but is of type " + defaultValue.getClass()
|
||||||
|
.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void importZonefiles(final String vmName, final String zonenfilesJson) {
|
||||||
|
if (zonenfilesJson == null || zonenfilesJson.isEmpty() || zonenfilesJson.isBlank()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//noinspection unchecked
|
||||||
|
final Map<String, Map<String, Object>> zoneData = jsonMapper.readValue(zonenfilesJson, Map.class);
|
||||||
|
importZonenfile(vmName, zoneData);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException("cannot read zonefile JSON: '" + zonenfilesJson + "'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void importZonenfile(final String vmName, final Map<String, Map<String, Object>> zoneDataForVM) {
|
||||||
|
zoneDataForVM.forEach((domainName, zoneData) -> {
|
||||||
|
final var domainAsset = domainSetupsByName.get(domainName);
|
||||||
|
if (domainAsset != null) {
|
||||||
|
final var domainDnsSetupAsset = domainAsset.getSubHostingAssets().stream()
|
||||||
|
.filter(subAsset -> subAsset.getType() == DOMAIN_DNS_SETUP)
|
||||||
|
.findAny().orElse(null);
|
||||||
|
assertThat(domainDnsSetupAsset).as(domainAsset.getIdentifier() + " has no DOMAIN_DNS_SETUP").isNotNull();
|
||||||
|
|
||||||
|
final var domUser = domainAsset.getSubHostingAssets().stream()
|
||||||
|
.filter(ha -> ha.getType() == DOMAIN_HTTP_SETUP)
|
||||||
|
.findAny().orElseThrow()
|
||||||
|
.getAssignedToAsset();
|
||||||
|
final var domOwner = zoneData.remove("DOM_OWNER");
|
||||||
|
final var expectedDomOwner = domUser.getIdentifier();
|
||||||
|
if (domOwner.equals(expectedDomOwner)) {
|
||||||
|
logError(() -> assertThat(vmName).isEqualTo(domUser.getParentAsset().getParentAsset().getIdentifier()));
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
zoneData.put("user-RR", ((ArrayList<ArrayList<Object>>) zoneData.get("user-RR")).stream()
|
||||||
|
.map(userRR -> userRR.stream().map(Object::toString).collect(Collectors.joining(" ")))
|
||||||
|
.toArray(String[]::new)
|
||||||
|
);
|
||||||
|
domainDnsSetupAsset.getConfig().putAll(zoneData);
|
||||||
|
} else {
|
||||||
|
logError("zonedata dom_owner of " + domainAsset.getIdentifier() + " is " + domOwner + " but expected to be "
|
||||||
|
+ expectedDomOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================================
|
// ============================================================================================
|
||||||
|
|
||||||
<V> V returning(
|
<V> V returning(
|
||||||
@ -1084,7 +1414,7 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
private String firstOfEachType(
|
private String firstOfEachType(
|
||||||
final int maxCount,
|
final int maxCount,
|
||||||
final HsHostingAssetType... types) {
|
final HsHostingAssetType... types) {
|
||||||
return toFormattedString(stream(types)
|
return toJsonFormattedString(stream(types)
|
||||||
.flatMap(t ->
|
.flatMap(t ->
|
||||||
hostingAssets.entrySet().stream()
|
hostingAssets.entrySet().stream()
|
||||||
.filter(hae -> hae.getValue().getType() == t)
|
.filter(hae -> hae.getValue().getType() == t)
|
||||||
@ -1100,7 +1430,7 @@ public class ImportHostingAssets extends ImportOfficeData {
|
|||||||
private String firstOfEachType(
|
private String firstOfEachType(
|
||||||
final int maxCount,
|
final int maxCount,
|
||||||
final HsBookingItemType... types) {
|
final HsBookingItemType... types) {
|
||||||
return toFormattedString(stream(types)
|
return toJsonFormattedString(stream(types)
|
||||||
.flatMap(t ->
|
.flatMap(t ->
|
||||||
bookingItems.entrySet().stream()
|
bookingItems.entrySet().stream()
|
||||||
.filter(bie -> bie.getValue().getType() == t)
|
.filter(bie -> bie.getValue().getType() == t)
|
||||||
|
@ -105,6 +105,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
|
|
||||||
// at least as the number of lines in business_partners.csv from test-data, but less than real data partner count
|
// at least as the number of lines in business_partners.csv from test-data, but less than real data partner count
|
||||||
public static final int MAX_NUMBER_OF_TEST_DATA_PARTNERS = 100;
|
public static final int MAX_NUMBER_OF_TEST_DATA_PARTNERS = 100;
|
||||||
|
public static final int DELIBERATELY_BROKEN_BUSINESS_PARTNER_ID = 199;
|
||||||
|
|
||||||
static int relationId = 2000000;
|
static int relationId = 2000000;
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
// no contacts yet => mostly null values
|
// no contacts yet => mostly null values
|
||||||
assertThat(toFormattedString(partners)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(partners)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=partner(P-10003: null null, null),
|
100=partner(P-10003: null null, null),
|
||||||
120=partner(P-10020: null null, null),
|
120=partner(P-10020: null null, null),
|
||||||
@ -164,8 +165,8 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
542=partner(P-11019: null null, null)
|
542=partner(P-11019: null null, null)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(contacts)).isEqualTo("{}");
|
assertThat(toJsonFormattedString(contacts)).isEqualTo("{}");
|
||||||
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(debitors)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=debitor(D-1000300: rel(anchor='null null, null', type='DEBITOR'), mim),
|
100=debitor(D-1000300: rel(anchor='null null, null', type='DEBITOR'), mim),
|
||||||
120=debitor(D-1002000: rel(anchor='null null, null', type='DEBITOR'), xyz),
|
120=debitor(D-1002000: rel(anchor='null null, null', type='DEBITOR'), xyz),
|
||||||
@ -178,7 +179,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
542=debitor(D-1101900: rel(anchor='null null, null', type='DEBITOR'), dph)
|
542=debitor(D-1101900: rel(anchor='null null, null', type='DEBITOR'), dph)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=Membership(M-1000300, P-10003, [2000-12-06,), ACTIVE),
|
100=Membership(M-1000300, P-10003, [2000-12-06,), ACTIVE),
|
||||||
120=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
120=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
||||||
@ -206,7 +207,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
void verifyContacts() {
|
void verifyContacts() {
|
||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
assertThat(toFormattedString(partners)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(partners)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=partner(P-10003: ?? Michael Mellis, Herr Michael Mellis , Michael Mellis),
|
100=partner(P-10003: ?? Michael Mellis, Herr Michael Mellis , Michael Mellis),
|
||||||
120=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract , JM GmbH),
|
120=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract , JM GmbH),
|
||||||
@ -219,7 +220,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
542=partner(P-11019: ?? Das Perfekte Haus, Herr Richard Wiese , Das Perfekte Haus)
|
542=partner(P-11019: ?? Das Perfekte Haus, Herr Richard Wiese , Das Perfekte Haus)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(contacts)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(contacts)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=contact(caption='Herr Michael Mellis , Michael Mellis', emailAddresses='{ "main": "michael@Mellis.example.org"}'),
|
100=contact(caption='Herr Michael Mellis , Michael Mellis', emailAddresses='{ "main": "michael@Mellis.example.org"}'),
|
||||||
1200=contact(caption='JM e.K.', emailAddresses='{ "main": "jm-ex-partner@example.org"}'),
|
1200=contact(caption='JM e.K.', emailAddresses='{ "main": "jm-ex-partner@example.org"}'),
|
||||||
@ -241,7 +242,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
90698=contact(caption='Jan Henning ', emailAddresses='{ "main": "mail@jan-henning.example.org"}')
|
90698=contact(caption='Jan Henning ', emailAddresses='{ "main": "mail@jan-henning.example.org"}')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(persons)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(persons)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=person(personType='??', tradeName='Michael Mellis', familyName='Mellis', givenName='Michael'),
|
100=person(personType='??', tradeName='Michael Mellis', familyName='Mellis', givenName='Michael'),
|
||||||
1200=person(personType='LP', tradeName='JM e.K.'),
|
1200=person(personType='LP', tradeName='JM e.K.'),
|
||||||
@ -263,7 +264,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
90698=person(personType='NP', familyName='Henning', givenName='Jan')
|
90698=person(personType='NP', familyName='Henning', givenName='Jan')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(debitors)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=debitor(D-1000300: rel(anchor='?? Michael Mellis', type='DEBITOR', holder='?? Michael Mellis'), mim),
|
100=debitor(D-1000300: rel(anchor='?? Michael Mellis', type='DEBITOR', holder='?? Michael Mellis'), mim),
|
||||||
120=debitor(D-1002000: rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH'), xyz),
|
120=debitor(D-1002000: rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH'), xyz),
|
||||||
@ -276,7 +277,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
542=debitor(D-1101900: rel(anchor='?? Das Perfekte Haus', type='DEBITOR', holder='?? Das Perfekte Haus'), dph)
|
542=debitor(D-1101900: rel(anchor='?? Das Perfekte Haus', type='DEBITOR', holder='?? Das Perfekte Haus'), dph)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=Membership(M-1000300, P-10003, [2000-12-06,), ACTIVE),
|
100=Membership(M-1000300, P-10003, [2000-12-06,), ACTIVE),
|
||||||
120=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
120=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
||||||
@ -286,7 +287,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
542=Membership(M-1101900, P-11019, [2021-05-25,), ACTIVE)
|
542=Membership(M-1101900, P-11019, [2021-05-25,), ACTIVE)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
2000000=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000000=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
||||||
2000001=rel(anchor='?? Michael Mellis', type='DEBITOR', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000001=rel(anchor='?? Michael Mellis', type='DEBITOR', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
||||||
@ -373,7 +374,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
void verifySepaMandates() {
|
void verifySepaMandates() {
|
||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
assertThat(toFormattedString(bankAccounts)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(bankAccounts)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
132=bankAccount(DE37500105177419788228: holder='Michael Mellis', bic='GENODEF1HH2'),
|
132=bankAccount(DE37500105177419788228: holder='Michael Mellis', bic='GENODEF1HH2'),
|
||||||
234234=bankAccount(DE37500105177419788228: holder='Michael Mellis', bic='INGDDEFFXXX'),
|
234234=bankAccount(DE37500105177419788228: holder='Michael Mellis', bic='INGDDEFFXXX'),
|
||||||
@ -384,7 +385,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
387=bankAccount(DE89370400440532013000: holder='Richard Wiese Das Perfekte Haus', bic='COBADEFFXXX')
|
387=bankAccount(DE89370400440532013000: holder='Richard Wiese Das Perfekte Haus', bic='COBADEFFXXX')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(sepaMandates)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(sepaMandates)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
132=SEPA-Mandate(DE37500105177419788228, HS-10003-20140801, 2013-12-01, [2013-12-01,)),
|
132=SEPA-Mandate(DE37500105177419788228, HS-10003-20140801, 2013-12-01, [2013-12-01,)),
|
||||||
234234=SEPA-Mandate(DE37500105177419788228, MH12345, 2004-06-12, [2004-06-15,)),
|
234234=SEPA-Mandate(DE37500105177419788228, MH12345, 2004-06-12, [2004-06-15,)),
|
||||||
@ -413,7 +414,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
void verifyCoopShares() {
|
void verifyCoopShares() {
|
||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
assertThat(toFormattedString(coopShares)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(coopShares)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
241=CoopShareTransaction(M-1000300: 2011-12-05, SUBSCRIPTION, 16, 1000300),
|
241=CoopShareTransaction(M-1000300: 2011-12-05, SUBSCRIPTION, 16, 1000300),
|
||||||
279=CoopShareTransaction(M-1015200: 2013-10-21, SUBSCRIPTION, 1, 1015200),
|
279=CoopShareTransaction(M-1015200: 2013-10-21, SUBSCRIPTION, 1, 1015200),
|
||||||
@ -446,7 +447,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
void verifyCoopAssets() {
|
void verifyCoopAssets() {
|
||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
assertThat(toFormattedString(coopAssets)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(coopAssets)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
1093=CoopAssetsTransaction(M-1000300: 2023-10-05, DEPOSIT, 3072, 1000300, Kapitalerhoehung - Ueberweisung),
|
1093=CoopAssetsTransaction(M-1000300: 2023-10-05, DEPOSIT, 3072, 1000300, Kapitalerhoehung - Ueberweisung),
|
||||||
1094=CoopAssetsTransaction(M-1000300: 2023-10-06, DEPOSIT, 3072, 1000300, Kapitalerhoehung - Ueberweisung),
|
1094=CoopAssetsTransaction(M-1000300: 2023-10-06, DEPOSIT, 3072, 1000300, Kapitalerhoehung - Ueberweisung),
|
||||||
@ -475,7 +476,7 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
void verifyMemberships() {
|
void verifyMemberships() {
|
||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=Membership(M-1000300, P-10003, [2000-12-06,), ACTIVE),
|
100=Membership(M-1000300, P-10003, [2000-12-06,), ACTIVE),
|
||||||
120=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
120=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
||||||
@ -494,11 +495,15 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
partners.forEach((id, p) -> {
|
partners.forEach((id, p) -> {
|
||||||
final var partnerRel = p.getPartnerRel();
|
final var partnerRel = p.getPartnerRel();
|
||||||
assertThat(partnerRel).describedAs("partner " + id + " without partnerRel").isNotNull();
|
assertThat(partnerRel).describedAs("partner " + id + " without partnerRel").isNotNull();
|
||||||
if ( id != 199 ) {
|
if (id != DELIBERATELY_BROKEN_BUSINESS_PARTNER_ID) {
|
||||||
logError( () -> assertThat(partnerRel.getContact()).describedAs("partner " + id + " without partnerRel.contact").isNotNull());
|
logError( () -> {
|
||||||
logError( () -> assertThat(partnerRel.getContact().getCaption()).describedAs("partner " + id + " without valid partnerRel.contact").isNotNull());
|
assertThat(partnerRel.getContact()).describedAs("partner " + id + " without partnerRel.contact").isNotNull();
|
||||||
logError( () -> assertThat(partnerRel.getHolder()).describedAs("partner " + id + " without partnerRel.relHolder").isNotNull());
|
assertThat(partnerRel.getContact().getCaption()).describedAs("partner " + id + " without valid partnerRel.contact").isNotNull();
|
||||||
logError( () -> assertThat(partnerRel.getHolder().getPersonType()).describedAs("partner " + id + " without valid partnerRel.relHolder").isNotNull());
|
});
|
||||||
|
logError( () -> {
|
||||||
|
assertThat(partnerRel.getHolder()).describedAs("partner " + id + " without partnerRel.relHolder").isNotNull();
|
||||||
|
assertThat(partnerRel.getHolder().getPersonType()).describedAs("partner " + id + " without valid partnerRel.relHolder").isNotNull();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -604,6 +609,13 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(9000)
|
@Order(9000)
|
||||||
|
@ContinueOnFailure
|
||||||
|
void logCollectedErrorsBeforePersist() {
|
||||||
|
assertNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(9010)
|
||||||
void persistOfficeEntities() {
|
void persistOfficeEntities() {
|
||||||
|
|
||||||
System.out.println("PERSISTING office data to database '" + jdbcUrl + "' as user '" + postgresAdminUser + "'");
|
System.out.println("PERSISTING office data to database '" + jdbcUrl + "' as user '" + postgresAdminUser + "'");
|
||||||
@ -716,6 +728,13 @@ public class ImportOfficeData extends CsvDataImport {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(9999)
|
||||||
|
@ContinueOnFailure
|
||||||
|
void logCollectedErrors() {
|
||||||
|
this.assertNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
private void importBusinessPartners(final String[] header, final List<String[]> records) {
|
private void importBusinessPartners(final String[] header, final List<String[]> records) {
|
||||||
|
|
||||||
final var columns = new Columns(header);
|
final var columns = new Columns(header);
|
||||||
|
10
src/test/resources/migration/hosting/domain.csv
Normal file
10
src/test/resources/migration/hosting/domain.csv
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
domain_id;domain_name;domain_since;domain_dns_master;domain_owner;valid_subdomain_names;passenger_python;passenger_nodejs;passenger_ruby;fcgi_php_bin;domainoptions
|
||||||
|
4531;l-u-g.org;2013-09-10;dns.hostsharing.net;5803;*;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;greylisting,multiviews,indexes,htdocsfallback,includes,cgi,fastcgi,passenger
|
||||||
|
4532;linuxfanboysngirls.de;2013-09-10;dns.hostsharing.net;5809;*;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;greylisting,multiviews,indexes,htdocsfallback,includes,cgi,fastcgi,passenger
|
||||||
|
4534;lug-mars.de;2013-09-10;dns.hostsharing.net;5809;www;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;greylisting,letsencrypt,multiviews,indexes,htdocsfallback,includes,cgi,fastcgi,passenger
|
||||||
|
4581;1981.ist-im-netz.de;2013-09-17;dns.hostsharing.net;5964;*;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;greylisting,multiviews,indexes,htdocsfallback,includes,cgi,fastcgi,passenger
|
||||||
|
4587;mellis.de;2013-09-17;dns.hostsharing.net;5964;www,michael,test,photos,static,input;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;htdocsfallback,indexes,includes,letsencrypt,multiviews,cgi,fastcgi,passenger
|
||||||
|
4589;ist-im-netz.de;2013-09-17;dns.hostsharing.net;5964;*;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;htdocsfallback,indexes,includes,letsencrypt,multiviews,cgi,fastcgi,passenger
|
||||||
|
4600;waera.de;2013-09-17;dns.hostsharing.net;5964;*;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;greylisting,multiviews,indexes,htdocsfallback,includes,cgi,fastcgi,passenger
|
||||||
|
4604;xn--wra-qla.de;2013-09-17;dns.hostsharing.net;5964;*;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;greylisting,multiviews,indexes,htdocsfallback,includes,cgi,fastcgi,passenger
|
||||||
|
27662;dph-netzwerk.de;2021-06-02;h93.hostsharing.net;169596;*;/usr/bin/python3;/usr/bin/node;/usr/bin/ruby;/usr/lib/cgi-bin/php;htdocsfallback,indexes,autoconfig,greylisting,includes,letsencrypt,multiviews,cgi,fastcgi,passenger
|
|
@ -5,8 +5,6 @@ emailalias_id;pac_id;name;target
|
|||||||
2431;1112;mim00-abruf;michael.mellis@hostsharing.net
|
2431;1112;mim00-abruf;michael.mellis@hostsharing.net
|
||||||
2449;1112;mim00-hhfx;"mim00-hhfx,""|/usr/bin/formail -I 'Reply-To: hamburger-fx@example.net' | /usr/lib/sendmail mim00-hhfx-l"""
|
2449;1112;mim00-hhfx;"mim00-hhfx,""|/usr/bin/formail -I 'Reply-To: hamburger-fx@example.net' | /usr/lib/sendmail mim00-hhfx-l"""
|
||||||
2451;1112;mim00-hhfx-l;:include:/home/pacs/mim00/etc/hhfx.list
|
2451;1112;mim00-hhfx-l;:include:/home/pacs/mim00/etc/hhfx.list
|
||||||
2452;1112;mim00-empty;
|
|
||||||
2453;1112;mim00-0_entries;""
|
|
||||||
2454;1112;mim00-dev.null; /dev/null
|
2454;1112;mim00-dev.null; /dev/null
|
||||||
2455;1112;mim00-1_with_space;" ""|/home/pacs/mim00/install/corpslistar/listar"""
|
2455;1112;mim00-1_with_space;" ""|/home/pacs/mim00/install/corpslistar/listar"""
|
||||||
2456;1112;mim00-1_with_single_quotes;'|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern'
|
2456;1112;mim00-1_with_single_quotes;'|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern'
|
||||||
|
|
@ -15,5 +15,5 @@ unixuser_id;name;comment;shell;homedir;locked;packet_id;userid;quota_softlimit;q
|
|||||||
|
|
||||||
167846;hsh00-dph;hsh00-uph;/bin/false;/home/pacs/hsh00/users/uph;0;630;110568;0;0;0;0
|
167846;hsh00-dph;hsh00-uph;/bin/false;/home/pacs/hsh00/users/uph;0;630;110568;0;0;0;0
|
||||||
169546;dph00;Reinhard Wiese;/bin/bash;/home/pacs/dph00;0;19959;110593;0;0;0;0
|
169546;dph00;Reinhard Wiese;/bin/bash;/home/pacs/dph00;0;19959;110593;0;0;0;0
|
||||||
169596;dph00-uph;Domain admin;/bin/bash;/home/pacs/dph00/users/uph;0;19959;110594;0;0;0;0
|
169596;dph00-dph;Domain admin;/bin/bash;/home/pacs/dph00/users/uph;0;19959;110594;0;0;0;0
|
||||||
|
|
||||||
|
|
@ -0,0 +1,274 @@
|
|||||||
|
{
|
||||||
|
"1981.ist-im-netz.de": {
|
||||||
|
"DOM_OWNER": "mim00",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": []
|
||||||
|
},
|
||||||
|
"mellis.de": {
|
||||||
|
"DOM_OWNER": "mim00",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": true,
|
||||||
|
"auto-AUTOCONFIG-RR": true,
|
||||||
|
"auto-AUTODISCOVER-RR": true,
|
||||||
|
"auto-DKIM-RR": true,
|
||||||
|
"auto-MAILSERVICES-RR": true,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": true,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": true,
|
||||||
|
"user-RR": [
|
||||||
|
[
|
||||||
|
"dump.hoennig.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"CNAME",
|
||||||
|
"mih12.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"fotos.hoennig.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"CNAME",
|
||||||
|
"mih12.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"maven.hoennig.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"NS",
|
||||||
|
"dns1.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key1._domainkey.mellis.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"TXT",
|
||||||
|
"\"v=DKIM1; k=rsa; t=s; h=sha256; s=email; \" \"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzAIotiz04KGTF9ECNxEmnnl6eTHplxxYJpOWhx3YiLbQyt6D+sN5uMa/\" \"RMIJDr5BzqzHDQPTM6esLldtIu4OpHppdu3PG4BUB8aXfA0EQvt0wQ/VFGNP36x87nfqs2L8NxbgPwhVD5RqFgj6aheTt64PB+VRco3Nc2qLF4iGpM9UlQbp/W2IITXPbLd9Z/qPo4S6Yeghsq4eFSlcNqSGyO42d23EbAxiehJKBu2eTKX5Vj+n06h1zuXOHyC5IwIe515hmS/\" \"kybbyTTEe35Rmuh+1W9aBJb85d34Thi+knUJeysFleHe7mXG7k6zFiG5HjaP7CvDzzdWvCcaJhOIqXwIDAQAB\""
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ist-im-netz.de": {
|
||||||
|
"DOM_OWNER": "mim00",
|
||||||
|
"TTL": 14400,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": false,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": [
|
||||||
|
[
|
||||||
|
"1981.ist-im-netz.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"NS",
|
||||||
|
"dns1.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"1981.ist-im-netz.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"NS",
|
||||||
|
"dns2.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"1981.ist-im-netz.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"NS",
|
||||||
|
"dns3.hostsharing.net."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"l-u-g.de": {
|
||||||
|
"DOM_OWNER": "lug00",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": []
|
||||||
|
},
|
||||||
|
"l-u-g.org": {
|
||||||
|
"DOM_OWNER": "lug00",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": []
|
||||||
|
},
|
||||||
|
"linuxfanboysngirls.de": {
|
||||||
|
"DOM_OWNER": "lug00-wla.2",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": []
|
||||||
|
},
|
||||||
|
"lug-mars.de": {
|
||||||
|
"DOM_OWNER": "lug00-wla.2",
|
||||||
|
"TTL": 14400,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": false,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": false,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": false,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": [
|
||||||
|
[
|
||||||
|
"lug-mars.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"SOA",
|
||||||
|
"dns1.hostsharing.net. hostmaster.hostsharing.net. 1611590905 10800 3600 604800 3600"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"lug-mars.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"MX",
|
||||||
|
"10 mailin1.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"lug-mars.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"MX",
|
||||||
|
"20 mailin2.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"lug-mars.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"MX",
|
||||||
|
"30 mailin3.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"bbb.lug-mars.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"A",
|
||||||
|
"83.223.79.72"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ftp.lug-mars.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"A",
|
||||||
|
"83.223.79.72"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"www.lug-mars.de.",
|
||||||
|
14400,
|
||||||
|
"IN",
|
||||||
|
"A",
|
||||||
|
"83.223.79.72"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"waera.de": {
|
||||||
|
"DOM_OWNER": "mim00",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": []
|
||||||
|
},
|
||||||
|
"xn--wra-qla.de": {
|
||||||
|
"DOM_OWNER": "mim00",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": []
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"dph-netzwerk.de": {
|
||||||
|
"DOM_OWNER": "dph00-dph",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": true,
|
||||||
|
"auto-AUTOCONFIG-RR": true,
|
||||||
|
"auto-AUTODISCOVER-RR": true,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": true,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": true,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": [
|
||||||
|
[
|
||||||
|
"dph-netzwerk.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"TXT",
|
||||||
|
"\"v=spf1 include:spf.hostsharing.net ?all\""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"*.dph-netzwerk.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"TXT",
|
||||||
|
"\"v=spf1 include:spf.hostsharing.net ?all\""
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mellis.de": {
|
||||||
|
"DOM_OWNER": "old00",
|
||||||
|
"TTL": 21600,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": true,
|
||||||
|
"auto-AUTOCONFIG-RR": true,
|
||||||
|
"auto-AUTODISCOVER-RR": true,
|
||||||
|
"auto-DKIM-RR": true,
|
||||||
|
"auto-MAILSERVICES-RR": true,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": true,
|
||||||
|
"auto-WILDCARD-MX-RR": true,
|
||||||
|
"auto-WILDCARD-SPF-RR": true,
|
||||||
|
"user-RR": [
|
||||||
|
[
|
||||||
|
"dump.mellis.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"CNAME",
|
||||||
|
"mih12.hostsharing.net."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key1._domainkey.mellis.de.",
|
||||||
|
21600,
|
||||||
|
"IN",
|
||||||
|
"TXT",
|
||||||
|
"\"v=DKIM1; k=rsa; t=s; h=sha256; s=email; \" \"p=OldFake+sN5uMa/\" \"OldFake/OldFake+OldFake/W2IITXPbLd9Z/OldFake+OldFake/\" \"OldFake+OldFake+OldFake\""
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ist-im-netz.de": {
|
||||||
|
"DOM_OWNER": "mim00",
|
||||||
|
"TTL": 700,
|
||||||
|
"auto-A-RR": true,
|
||||||
|
"auto-AAAA-RR": false,
|
||||||
|
"auto-AUTOCONFIG-RR": false,
|
||||||
|
"auto-AUTODISCOVER-RR": false,
|
||||||
|
"auto-DKIM-RR": false,
|
||||||
|
"auto-MAILSERVICES-RR": false,
|
||||||
|
"auto-MX-RR": true,
|
||||||
|
"auto-NS-RR": true,
|
||||||
|
"auto-SOA": true,
|
||||||
|
"auto-SPF-RR": false,
|
||||||
|
"auto-WILDCARD-A-RR": true,
|
||||||
|
"auto-WILDCARD-AAAA-RR": false,
|
||||||
|
"auto-WILDCARD-MX-RR": false,
|
||||||
|
"auto-WILDCARD-SPF-RR": false,
|
||||||
|
"user-RR": []
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user