diff --git a/automation/roles/bubble/tasks/main.yml b/automation/roles/bubble/tasks/main.yml index d5ac6027..62b2eabe 100644 --- a/automation/roles/bubble/tasks/main.yml +++ b/automation/roles/bubble/tasks/main.yml @@ -134,16 +134,21 @@ - import_tasks: restore.yml -- name: Install refresh_bubble_ssh_keys script and monitor +- name: Install refresh_bubble_ssh_keys monitor copy: - src: "{{ item }}" - dest: "/usr/local/sbin/{{ item }}" + src: "refresh_bubble_ssh_keys.sh" + dest: "/usr/local/sbin/refresh_bubble_ssh_keys.sh" + owner: root + group: root + mode: 0500 + +- name: Install refresh_bubble_ssh_keys script + template: + src: refresh_bubble_ssh_keys.sh.j2 + dest: /usr/local/sbin/refresh_bubble_ssh_keys.sh owner: root group: root mode: 0500 - with_items: - - "refresh_bubble_ssh_keys.sh" - - "refresh_bubble_ssh_keys_monitor.sh" - name: Install refresh_bubble_ssh_keys_monitor supervisor conf file copy: diff --git a/automation/roles/bubble/files/refresh_bubble_ssh_keys.sh b/automation/roles/bubble/templates/refresh_bubble_ssh_keys.sh.j2 similarity index 76% rename from automation/roles/bubble/files/refresh_bubble_ssh_keys.sh rename to automation/roles/bubble/templates/refresh_bubble_ssh_keys.sh.j2 index 0a7b4f62..f623fac5 100644 --- a/automation/roles/bubble/files/refresh_bubble_ssh_keys.sh +++ b/automation/roles/bubble/templates/refresh_bubble_ssh_keys.sh.j2 @@ -35,6 +35,17 @@ for key in $(echo "${CURRENT_KEYS_SQL}" | PGPASSWORD="$(cat /home/bubble/.BUBBLE fi done +# Retain self-generated ansible setup key +ANSIBLE_USER="{{node.user}}" +if [[ ! -z "${ANSIBLE_USER}" ]] ; then + PUB_FILE="$(cd ~${ANSIBLE_USER} && pwd)/.ssh/bubble_rsa.pub" + if [[ -f "${PUB_FILE}" ]] ; then + cat "${PUB_FILE}" >> ${NEW_KEYS} + fi +else + log "Warning: No ansible user defined, unable to retain setup key" +fi + mv ${NEW_KEYS} ${AUTH_KEYS} || die "Error moving ${NEW_KEYS} -> ${AUTH_KEYS}" log "Installed new SSH keys ${NEW_KEYS} -> ${AUTH_KEYS}" diff --git a/bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java b/bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java index 9b148c15..9d0c7296 100644 --- a/bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java +++ b/bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java @@ -37,8 +37,10 @@ public class BubbleNetworkDAO extends AccountOwnedEntityDAO { @Autowired private BubbleConfiguration configuration; @Override public Object preCreate(BubbleNetwork network) { - final ValidationResult errors = validateHostname(network); - if (errors.isInvalid()) throw invalidEx(errors); + if (!network.hasForkHost()) { + final ValidationResult errors = validateHostname(network); + if (errors.isInvalid()) throw invalidEx(errors); + } if (!network.hasLocale()) network.setLocale(getDEFAULT_LOCALE()); return super.preCreate(network); diff --git a/bubble-server/src/main/java/bubble/model/bill/AccountPlan.java b/bubble-server/src/main/java/bubble/model/bill/AccountPlan.java index 1b10497e..f8f4545f 100644 --- a/bubble-server/src/main/java/bubble/model/bill/AccountPlan.java +++ b/bubble-server/src/main/java/bubble/model/bill/AccountPlan.java @@ -40,7 +40,7 @@ public class AccountPlan extends IdentifiableBase implements HasAccount { public static final String[] UPDATE_FIELDS = {"description", "paymentMethod", "paymentMethodObject"}; public static final String[] CREATE_FIELDS = ArrayUtil.append(UPDATE_FIELDS, - "name", "locale", "timezone", "domain", "network", "sshKey", "plan", "footprint"); + "name", "forkHost", "locale", "timezone", "domain", "network", "sshKey", "plan", "footprint"); @SuppressWarnings("unused") public AccountPlan (AccountPlan other) { copy(this, other, CREATE_FIELDS); } diff --git a/bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java b/bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java index 21cba2a4..66262a44 100644 --- a/bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java +++ b/bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java @@ -139,7 +139,8 @@ public class BubbleNetwork extends IdentifiableBase implements HasNetwork, HasBu @Embedded @Getter @Setter private BubbleTags tags; @Transient @Getter @Setter private transient String forkHost; - public boolean fork() { return forkHost != null; } + public boolean hasForkHost () { return !empty(forkHost); } + public boolean fork() { return hasForkHost(); } @ECSearchable @ECField(index=120) @Column(length=20) diff --git a/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java b/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java index 7c452ccb..9634d8ba 100644 --- a/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java +++ b/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java @@ -2,7 +2,6 @@ package bubble.resources.bill; import bubble.cloud.CloudServiceType; import bubble.cloud.geoLocation.GeoLocation; -import bubble.dao.account.AccountPolicyDAO; import bubble.dao.account.AccountSshKeyDAO; import bubble.dao.bill.AccountPaymentMethodDAO; import bubble.dao.bill.AccountPlanDAO; @@ -24,6 +23,7 @@ import bubble.resources.account.AccountOwnedResource; import bubble.server.BubbleConfiguration; import bubble.service.AuthenticatorService; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.util.StringUtil; import org.cobbzilla.wizard.validation.ValidationResult; import org.glassfish.grizzly.http.server.Request; import org.glassfish.jersey.server.ContainerRequest; @@ -38,15 +38,14 @@ import java.util.List; import java.util.stream.Collectors; import static bubble.ApiConstants.*; -import static org.cobbzilla.util.string.ValidationRegexes.HOST_PART_PATTERN; -import static org.cobbzilla.util.string.ValidationRegexes.validateRegexMatches; +import static bubble.model.cloud.BubbleNetwork.validateHostname; +import static org.cobbzilla.util.string.ValidationRegexes.*; import static org.cobbzilla.wizard.resources.ResourceUtil.*; @Slf4j public class AccountPlansResource extends AccountOwnedResource { @Autowired private AccountSshKeyDAO sshKeyDAO; - @Autowired private AccountPolicyDAO policyDAO; @Autowired private BubbleDomainDAO domainDAO; @Autowired private BubbleNetworkDAO networkDAO; @Autowired private BubblePlanDAO planDAO; @@ -117,16 +116,6 @@ public class AccountPlansResource extends AccountOwnedResource "${AUTH_KEYS}" || die "Error updating ${AUTH_KEYS} file" -cat "${PUB_FILE}" >> "${AUTH_KEYS}" || die "Error updating ${AUTH_KEYS} file" +cat "${PUB_FILE}" > "${AUTH_KEYS}" || die "Error updating ${AUTH_KEYS} file" sudo apt-get update -y && apt-get upgrade -y || die "Error in apt update / upgrade" sudo apt-get -y install python3 python3-pip virtualenv || die "Error apt installing python3 or python3-pip" diff --git a/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties b/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties index 5a80b92f..4c786a8b 100644 --- a/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties +++ b/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties @@ -427,6 +427,7 @@ err.expiration.cannotCreateSshKeyAlreadyExpired=Expiration date has already pass err.footprint.required=Footprint is required err.forkHost.notAllowed=Fork Host is not allowed err.forkHost.invalid=Fork Host is not a valid hostname +err.forkHost.domainMismatch=Fork Host domain does not match selected domain name err.fqdn.domain.invalid=Domain not found for FQDN err.fqdn.length=FQDN is too long err.fqdn.network.invalid=network not found for FQDN diff --git a/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java b/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java index 8e64c3b5..60a4b764 100644 --- a/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java +++ b/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java @@ -66,7 +66,7 @@ public abstract class BubbleModelTestBase extends ApiModelTestBase