Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9522b8aa8d | |||
| fd881b4c61 | |||
| 424ca715c9 | |||
| fe3c5f7a1b | |||
| e601fc93d6 | |||
| 8f7076e4ef |
@@ -3118,3 +3118,7 @@
|
||||
* backup: add synology C2
|
||||
* mail: update haraka to 3.1.2
|
||||
* csp/robots: add common patterns
|
||||
|
||||
[9.0.18]
|
||||
* ami & cloud images: fix setup
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
||||
const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { TextInput, InputGroup, MaskedInput, Button, FormGroup, Checkbox, SingleSelect } from '@cloudron/pankow';
|
||||
import { ENDPOINTS_OVH } from '../constants.js';
|
||||
import DomainsModel from '../models/DomainsModel.js';
|
||||
@@ -53,15 +53,6 @@ function needsPort80(dnsProvider, tlsProvider) {
|
||||
(tlsProvider === 'letsencrypt-prod' || tlsProvider === 'letsencrypt-staging'));
|
||||
}
|
||||
|
||||
function setDefaultTlsProvider(p) {
|
||||
// wildcard LE won't work without automated DNS
|
||||
if (p === 'manual' || p === 'noop' || p === 'wildcard') {
|
||||
tlsProvider.value = 'letsencrypt-prod';
|
||||
} else {
|
||||
tlsProvider.value = 'letsencrypt-prod-wildcard';
|
||||
}
|
||||
}
|
||||
|
||||
function resetFields() {
|
||||
dnsConfig.value.accessKeyId = '';
|
||||
dnsConfig.value.accessKey = '';
|
||||
@@ -86,10 +77,16 @@ function resetFields() {
|
||||
dnsConfig.value.username = '';
|
||||
}
|
||||
|
||||
function onProviderChange(p) {
|
||||
setDefaultTlsProvider(p);
|
||||
resetFields(p);
|
||||
}
|
||||
watch(provider, (p) => {
|
||||
resetFields();
|
||||
|
||||
// wildcard LE won't work without automated DNS
|
||||
if (p === 'manual' || p === 'noop' || p === 'wildcard') {
|
||||
tlsProvider.value = 'letsencrypt-prod';
|
||||
} else {
|
||||
tlsProvider.value = 'letsencrypt-prod-wildcard';
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
const gcdnsFileParseError = ref('');
|
||||
function onGcdnsFileInputChange(event) {
|
||||
@@ -130,7 +127,7 @@ function onGcdnsFileInputChange(event) {
|
||||
<div>
|
||||
<FormGroup>
|
||||
<label for="providerInput">{{ $t('domains.domainDialog.provider') }} <sup><a href="https://docs.cloudron.io/domains/#dns-providers" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
||||
<SingleSelect v-model="provider" @select="onProviderChange" :disabled="disabled" :options="DomainsModel.providers" option-key="value" option-label="name" required />
|
||||
<SingleSelect v-model="provider" :disabled="disabled" :options="DomainsModel.providers" option-key="value" option-label="name" required />
|
||||
</FormGroup>
|
||||
|
||||
<div class="warning-label" v-show="provider === 'wildcard'" v-html="$t('domains.domainDialog.wildcardInfo', { domain: domain })"></div>
|
||||
@@ -323,7 +320,7 @@ function onGcdnsFileInputChange(event) {
|
||||
|
||||
<FormGroup v-if="showAdvanced">
|
||||
<label>Certificate provider <sup><a href="https://docs.cloudron.io/certificates/#certificate-providers" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
||||
<SingleSelect v-model="tlsProvider" :options="tlsProviders" option-key="value" option-label="name"/>
|
||||
<SingleSelect v-model="tlsProvider" :options="tlsProviders" option-key="value" option-label="name" required/>
|
||||
</FormGroup>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ const ipProviders = [
|
||||
{ name: 'Network Interface', value: 'network-interface' }
|
||||
];
|
||||
|
||||
const serverProvider = ref('');
|
||||
const formError = ref({});
|
||||
const busy = ref(false);
|
||||
const ready = ref(false);
|
||||
@@ -27,11 +28,10 @@ const progressMessage = ref('');
|
||||
const taskMinutesActive = ref(0);
|
||||
const domain = ref('');
|
||||
const instanceId = ref('');
|
||||
const setupToken = ref('');
|
||||
const zoneName = ref('');
|
||||
const provider = ref('');
|
||||
const dnsConfig = ref(DomainsModel.createEmptyConfig());
|
||||
const tlsProvider = ref('letsenc-prod-wildcard');
|
||||
const tlsProvider = ref('letsencrypt-prod-wildcard');
|
||||
const showAdvanced = ref(false);
|
||||
const customNameservers = ref(false);
|
||||
const ipv4Provider = ref('generic');
|
||||
@@ -59,7 +59,7 @@ async function waitForDnsSetup () {
|
||||
|
||||
if (!result.setup.active) {
|
||||
if (!result.adminFqdn || result.setup.errorMessage) { // setup reset or errored. start over
|
||||
formError.value.dnsWait = result.setup.errorMessage;
|
||||
formError.value.generic = result.setup.errorMessage;
|
||||
waitingForDnsSetup.value = false;
|
||||
} else { // proceed to activation
|
||||
window.location.href = 'https://' + result.adminFqdn + '/activation.html' + (window.location.search);
|
||||
@@ -100,23 +100,13 @@ async function onSubmit() {
|
||||
ip: ipv6Provider.value === 'fixed' ? ipv6Address.value : '',
|
||||
ifname: ipv6Provider.value === 'network-interface' ? ipv6Interface.value : '',
|
||||
},
|
||||
providerToken: instanceId.value,
|
||||
setupToken: setupToken.value,
|
||||
providerToken: instanceId.value, // currently only for AMI
|
||||
};
|
||||
|
||||
const [error] = await provisionModel.setup(data);
|
||||
busy.value = false; // so we can come back to this view if dns setup errors later
|
||||
if (error) {
|
||||
if (error.status === 422) {
|
||||
if (provider.value === 'ami') {
|
||||
formError.value.ami = error.body.message;
|
||||
} else {
|
||||
formError.value.setup = error.body.message;
|
||||
}
|
||||
} else {
|
||||
formError.value.generic = error.body ? error.body.message : 'Internal error';
|
||||
}
|
||||
|
||||
formError.value.generic = error.body ? error.body.message : 'Internal error';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,26 +123,23 @@ watchEffect(() => {
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const search = decodeURIComponent(window.location.search).slice(1).split('&').map(function (item) { return item.split('='); }).reduce(function (o, k) { o[k[0]] = k[1]; return o; }, {});
|
||||
|
||||
const [error, status] = await provisionModel.status();
|
||||
if (error) return console.error(error);
|
||||
|
||||
if (redirectIfNeeded(status, 'setup')) return; // redirected to some other view...
|
||||
|
||||
if (status.provider === 'digitalocean' || status.provider === 'digitalocean-mp') {
|
||||
serverProvider.value = status.provider;
|
||||
if (serverProvider.value === 'digitalocean' || serverProvider.value === 'digitalocean-mp') {
|
||||
provider.value = 'digitalocean';
|
||||
} else if (status.provider === 'linode' || status.provider === 'linode-oneclick' || status.provider === 'linode-stackscript') {
|
||||
} else if (serverProvider.value === 'linode' || serverProvider.value === 'linode-oneclick' || serverProvider.value === 'linode-stackscript') {
|
||||
provider.value = 'linode';
|
||||
} else if (status.provider === 'vultr' || status.provider === 'vultr-mp') {
|
||||
} else if (serverProvider.value === 'vultr' || serverProvider.value === 'vultr-mp') {
|
||||
provider.value = 'vultr';
|
||||
} else if (status.provider === 'gce') {
|
||||
} else if (serverProvider.value === 'gce') {
|
||||
provider.value = 'gcdns';
|
||||
} else if (status.provider === 'ami') {
|
||||
// aws marketplace made a policy change that they one cannot provide route53 IAM credentials
|
||||
provider.value = 'wildcard';
|
||||
} else { // some default to make the form not feel "empty"
|
||||
provider.value = 'digitalocean';
|
||||
} else if (serverProvider.value === 'ami') {
|
||||
// aws marketplace made a policy change that they one cannot provide route53 IAM credentials
|
||||
// we used to have wildcard here but it shows some ugly warnings
|
||||
}
|
||||
|
||||
const [error2, result] = await provisionModel.detectIp();
|
||||
@@ -161,9 +148,6 @@ onMounted(async () => {
|
||||
ipv4Provider.value = result.ipv4 ? 'generic' : 'noop';
|
||||
ipv6Provider.value = result.ipv6 ? 'generic' : 'noop';
|
||||
|
||||
instanceId.value = search.instanceId;
|
||||
setupToken.value = search.setupToken;
|
||||
|
||||
ready.value = true;
|
||||
|
||||
if (status.setup.active) return waitForDnsSetup();
|
||||
@@ -189,14 +173,18 @@ onMounted(async () => {
|
||||
<div class="view" v-else style="max-width: 500px">
|
||||
<h1 style="text-align: center">Domain Setup</h1>
|
||||
|
||||
<div class="text-danger" v-if="formError.dnsWait">{{ formError.dnsWait }}</div>
|
||||
<div class="text-danger" v-if="formError.setup">{{ formError.setup }}</div>
|
||||
<div class="text-danger" v-if="formError.generic">{{ formError.generic }}</div>
|
||||
|
||||
<form ref="form" @submit.prevent="onSubmit()" @input="checkValidity()">
|
||||
<fieldset :disabled="busy">
|
||||
<input type="submit" style="display: none"/>
|
||||
|
||||
<FormGroup v-if="serverProvider === 'ami'">
|
||||
<label for="amiInstanceIdInput">EC2 Instance ID</label>
|
||||
<TextInput id="amiInstanceIdInput" v-model="instanceId" placeholder="i-0123456789abcdef0" required />
|
||||
<small class="helper-text">Can be found in the AWS Console</small>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<label for="domainInput">Domain <sup><a href="https://docs.cloudron.io/installation/#domain-setup" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
||||
<TextInput id="domainInput" v-model="domain" placeholder="example.com" required />
|
||||
|
||||
@@ -48,6 +48,7 @@ const apps = require('./apps.js'),
|
||||
semver = require('semver'),
|
||||
settings = require('./settings.js'),
|
||||
superagent = require('@cloudron/superagent'),
|
||||
system = require('./system.js'),
|
||||
users = require('./users.js'),
|
||||
volumes = require('./volumes.js');
|
||||
|
||||
@@ -103,6 +104,7 @@ async function getState() {
|
||||
const mailStats = await Promise.all(mailDomains.map(d => mail.getStats(d.domain)));
|
||||
|
||||
const state = {
|
||||
provider: system.getProvider(),
|
||||
userCount: (await users.list()).length,
|
||||
groupCount: (await groups.list()).length,
|
||||
domains: (await domains.list()).map(d => d.provider),
|
||||
|
||||
Reference in New Issue
Block a user