Ver código fonte

start adding restore functionality

pull/1/head
Jonathan Cobb 4 anos atrás
pai
commit
a104db8906
7 arquivos alterados com 178 adições e 30 exclusões
  1. +11
    -1
      src/_services/network.service.js
  2. +49
    -4
      src/_store/networks.module.js
  3. +102
    -5
      src/account/NetworkPage.vue
  4. +13
    -17
      src/account/NetworksPage.vue
  5. +1
    -1
      src/account/NewNetworkPage.vue
  6. +1
    -1
      src/account/profile/ActionPage.vue
  7. +1
    -1
      src/auth/MultifactorAuthPage.vue

+ 11
- 1
src/_services/network.service.js Ver arquivo

@@ -9,7 +9,9 @@ export const networkService = {
getStatusesByNetworkId,
getNodesByNetworkId,
stopNetwork,
deleteNetwork
deleteNetwork,
requestNetworkKeys,
retrieveNetworkKeys
};

function getAllNetworks(userId, messages, errors) {
@@ -46,3 +48,11 @@ function stopNetwork(userId, networkId, messages, errors) {
function deleteNetwork(userId, networkId, messages, errors) {
return fetch(`${config.apiUrl}/users/${userId}/plans/${networkId}`, util.deleteWithAuth()).then(util.handleCrudResponse(messages, errors));
}

function requestNetworkKeys(userId, networkId, messages, errors) {
return fetch(`${config.apiUrl}/users/${userId}/networks/${networkId}/actions/keys`, util.getWithAuth()).then(util.handleCrudResponse(messages, errors));
}

function retrieveNetworkKeys(userId, networkId, code, password, messages, errors) {
return fetch(`${config.apiUrl}/users/${userId}/networks/${networkId}/actions/keys/${code}`, util.postWithAuth({name: 'password', value: password})).then(util.handleCrudResponse(messages, errors));
}

+ 49
- 4
src/_store/networks.module.js Ver arquivo

@@ -5,7 +5,8 @@ import { util } from '../_helpers';
const state = {
loading: {
networks: false, network: false, deleting: false,
nearestRegions: false, startingNetwork: false, networkStatuses: false, networkNodes: false
nearestRegions: false, startingNetwork: false, networkStatuses: false, networkNodes: false,
requestNetworkKeys: false, retrieveNetworkKeys: false
},
creating: null,
error: null,
@@ -14,7 +15,9 @@ const state = {
nearestRegions: null,
newNodeNotification: null,
networkStatuses: {},
networkNodes: null
networkNodes: null,
networkKeysRequested: null,
networkKeys: null
};

const actions = {
@@ -70,7 +73,7 @@ const actions = {
},

stopNetwork({ commit }, {userId, networkId, messages, errors}) {
commit('stopNetworkRequest', id);
commit('stopNetworkRequest', networkId);
networkService.stopNetwork(userId, networkId, messages, errors)
.then(
network => commit('stopNetworkSuccess', network),
@@ -79,7 +82,7 @@ const actions = {
},

deleteNetwork({ commit }, {userId, networkId, messages, errors}) {
commit('deleteNetworkRequest', id);
commit('deleteNetworkRequest', networkId);
networkService.deleteNetwork(userId, networkId, messages, errors)
.then(
network => commit('deleteNetworkSuccess', network),
@@ -95,6 +98,24 @@ const actions = {
error => commit('getNearestRegionsFailure', error)
);
},

requestNetworkKeys({ commit }, {userId, networkId, messages, errors}) {
commit('requestNetworkKeysRequest');
networkService.requestNetworkKeys(userId, networkId, messages, errors)
.then(
ok => commit('requestNetworkKeysSuccess', networkId),
error => commit('requestNetworkKeysFailure', error)
);
},

retrieveNetworkKeys({ commit }, {userId, networkId, code, password, messages, errors}) {
commit('retrieveNetworkKeysRequest');
networkService.retrieveNetworkKeys(userId, networkId, code, password, messages, errors)
.then(
keys => commit('retrieveNetworkKeysSuccess', keys),
error => commit('retrieveNetworkKeysFailure', error)
);
}
};

const mutations = {
@@ -200,6 +221,30 @@ const mutations = {
getNearestRegionsFailure(state, error) {
state.loading.nearestRegions = false;
state.error = { error };
},

requestNetworkKeysRequest(state) {
state.loading.requestNetworkKeys = true;
},
requestNetworkKeysSuccess(state, networkId) {
state.loading.requestNetworkKeys = false;
state.networkKeysRequested = networkId;
},
requestNetworkKeysFailure(state, error) {
state.loading.requestNetworkKeys = false;
state.error = { error };
},

retrieveNetworkKeysRequest(state) {
state.loading.retrieveNetworkKeys = true;
},
retrieveNetworkKeysSuccess(state, keys) {
state.loading.retrieveNetworkKeys = false;
state.networkKeys = keys;
},
retrieveNetworkKeysFailure(state, error) {
state.loading.retrieveNetworkKeys = false;
state.error = { error };
}
};



+ 102
- 5
src/account/NetworkPage.vue Ver arquivo

@@ -2,6 +2,7 @@
<div v-if="network">
<h4>{{network.name}}.{{network.domainName}} - <i>{{messages['msg_network_state_'+network.state]}}</i></h4>
<div v-if="stats">
<!-- adapted from: https://code-boxx.com/simple-vanilla-javascript-progress-bar/ -->
<div class="progress-wrap">
<div class="progress-bar" :style="'width: '+stats.percent+'%'" :id="'progressBar_'+networkId"></div>
<div class="progress-text">{{messages.label_percent.parseMessage(this, {percent: stats.percent})}}</div>
@@ -38,6 +39,54 @@
</table>
</div>

<div v-if="network.state === 'running'">
<button @click="requestRestoreKey()">{{messages.link_network_action_request_keys}}</button>
<div v-if="errors.has('networkKeys')" class="invalid-feedback d-block">{{ errors.first('networkKeys') }}</div>
<div v-if="networkKeysRequested && networkKeysRequested === networkId">{{messages.message_network_action_keys_requested}}</div>

<h5>{{messages.message_network_action_retrieve_keys}}</h5>
<form @submit.prevent="retrieveRestoreKey()">
<div class="form-group">
<label for="restoreKeyCode">{{messages.field_network_key_download_code}}</label>
<input type="text" v-model="restoreKeyCode" v-validate="'required'" name="restoreKeyCode" class="form-control" :class="{ 'is-invalid': errors.has('retrieveNetworkKeys') }" />
<div v-if="errors.has('retrieveNetworkKeys')" class="invalid-feedback">{{ errors.first('retrieveNetworkKeys') }}</div>
</div>
<div class="form-group">
<label for="restoreKeyPassword">{{messages.field_network_key_download_password}}</label>
<input type="text" v-model="restoreKeyPassword" v-validate="'required'" name="restoreKeyPassword" class="form-control" :class="{ 'is-invalid': errors.has('password') }" />
<div v-if="errors.has('password')" class="invalid-feedback">{{ errors.first('password') }}</div>
</div>
<button>{{messages.button_label_retrieve_keys}}</button>
<div v-if="networkKeys">
<hr/>
<h4><b>{{messages.message_network_keys}}</b></h4>: {{networkKeys}}
<hr/>
{{messages.message_network_keys_description}}
</div>
</form>
</div>

<div v-if="network.state === 'stopped'">
<!-- todo: add button to restart network in restore mode -->
</div>

<div>
<hr/>
<div class="text-danger"><h4>{{messages.title_network_danger_zone}}</h4></div>
<div v-if="errors.has('node')" class="invalid-feedback d-block">{{ errors.first('node') }}</div>
<div v-if="network.state === 'running'" style="border: 2px solid #000;">
<hr/>
<button @click="stopNet()" class="text-danger">{{messages.link_network_action_stop}}</button>
{{messages.link_network_action_stop_description}}
</div>
<div v-else></div>
<hr/>
<div style="border: 2px solid #000;">
<button @click="deleteNet()" class="text-danger">{{messages.link_network_action_delete}}</button>
{{messages.link_network_action_delete_description}}
</div>
</div>

</div>
</template>

@@ -48,17 +97,25 @@
export default {
data() {
return {
user: util.currentUser(),
networkId: this.$route.params.id,
stats: null,
refresher: null
refresher: null,
restoreKeyCode: null,
restoreKeyPassword: null
};
},
computed: {
...mapState('networks', ['network', 'newNodeNotification', 'networkStatuses', 'networkNodes']),
...mapState('networks', [
'network', 'newNodeNotification', 'networkStatuses', 'networkNodes', 'networkKeysRequested', 'networkKeys'
]),
...mapState('system', ['messages'])
},
methods: {
...mapActions('networks', ['getNetworkById', 'deleteNetwork', 'getStatusesByNetworkId', 'getNodesByNetworkId']),
...mapActions('networks', [
'getNetworkById', 'deleteNetwork', 'getStatusesByNetworkId', 'getNodesByNetworkId',
'stopNetwork', 'deleteNetwork', 'requestNetworkKeys'
]),
...mapGetters('networks', ['loading']),
refreshStatus (userId) {
this.getNetworkById({userId: userId, networkId: this.networkId, messages: this.messages, errors: this.errors});
@@ -78,6 +135,44 @@
},
startStatusRefresher (user) {
this.refresher = setInterval(() => this.refreshStatus(user.uuid), 5000);
},
stopNet () {
this.errors.clear();
this.stopNetwork({
userId: this.user.uuid,
networkId: this.networkId,
messages: this.messages,
errors: this.errors
});
},
deleteNet () {
this.errors.clear();
this.deleteNetwork({
userId: this.user.uuid,
networkId: this.networkId,
messages: this.messages,
errors: this.errors
});
},
requestRestoreKey () {
this.errors.clear();
this.requestNetworkKeys({
userId: this.user.uuid,
networkId: this.networkId,
messages: this.messages,
errors: this.errors
});
},
retrieveRestoreKey () {
this.errors.clear();
this.retrieveNetworkKeys({
userId: this.user.uuid,
networkId: this.networkId,
code: this.restoreKeyCode,
password: this.restoreKeyPassword,
messages: this.messages,
errors: this.errors
});
}
},
created () {
@@ -93,10 +188,12 @@
// console.log('watch.networkNodes: received: '+JSON.stringify(nodes));
},
networkStatuses (stats) {
console.log('received stats: '+JSON.stringify(stats));
if (stats) {
// adapted from: https://code-boxx.com/simple-vanilla-javascript-progress-bar/
if (!stats.hasOwnProperty(this.networkId)) return;
if (stats[this.networkId].length === 0) {
clearInterval(this.refresher);
return;
}
this.stats = stats[this.networkId][0]; // todo: when we have multiple nodes, this will need to be changed
if (this.stats.percent === 100) {
clearInterval(this.refresher);


+ 13
- 17
src/account/NetworksPage.vue Ver arquivo

@@ -10,27 +10,14 @@
<th nowrap="nowrap">{{messages.label_field_networks_locale}}</th>
<th nowrap="nowrap">{{messages.label_field_networks_timezone}}</th>
<th nowrap="nowrap">{{messages.label_field_networks_object_state}}</th>
<th nowrap="nowrap">{{messages.label_field_networks_action_view}}</th>
<th nowrap="nowrap">{{messages.label_field_networks_action_stop}}</th>
<th nowrap="nowrap">{{messages.label_field_networks_action_delete}}</th>
</tr>
</thead>
<tbody>
<tr v-for="network in networks" :key="network.uuid">
<td>{{network.name}}.{{network.domainName}}</td>
<td><router-link :to="{ path: '/bubble/'+ network.name }">{{network.name}}.{{network.domainName}}</router-link></td>
<td nowrap="nowrap">{{messages['locale_'+network.locale] || network.locale}}</td>
<td nowrap="nowrap">{{messages['tz_name_'+network.timezone] || network.timezone}}</td>
<td>{{messages['msg_network_state_'+network.state]}}</td>
<td><router-link :to="{ path: '/bubble/'+ network.name }">{{messages.table_row_networks_action_view}}</router-link></td>

<td v-if="network.state === 'running'">
<a @click="stopNetwork(network.uuid)" class="text-danger">{{messages.table_row_networks_action_stop}}</a>
</td>
<td v-else></td>

<td>
<a @click="deleteNetwork(network.uuid)" class="text-danger">{{messages.table_row_networks_action_delete}}</a>
</td>
</tr>
</tbody>
</table>
@@ -52,9 +39,7 @@

export default {
computed: {
...mapState({
networks: state => state.networks.networks
}),
...mapState('networks', ['networks']),
...mapState('system', ['messages'])
},
created () {
@@ -63,6 +48,17 @@
methods: {
...mapActions('networks', ['getAllNetworks', 'stopNetwork', 'deleteNetwork']),
...mapGetters('networks', ['loading'])
},
watch: {
networks (nets) {
if (nets && nets.length) {
if (nets.length === 0) {
this.$router.replace({path: '/bubble/new'});
} else if (nets.length === 1 && util.currentUser().admin !== true) {
this.$router.replace({path: '/bubble/' + nets[0].name});
}
}
}
}
};
</script>

+ 1
- 1
src/account/NewNetworkPage.vue Ver arquivo

@@ -228,7 +228,7 @@
accountPlan: {
name: '',
domain: '',
locale: '',
locale: util.currentUser().locale,
timezone: '',
plan: 'bubble',
footprint: 'Worldwide',


+ 1
- 1
src/account/profile/ActionPage.vue Ver arquivo

@@ -42,7 +42,7 @@
errors: this.errors
});
} else {
this.$router.push({path:'/me/profile', params: {'action': 'invalid'}});
this.$router.push({path:'/me/profile', params: {action: 'invalid'}});
}
},
watch: {


+ 1
- 1
src/auth/MultifactorAuthPage.vue Ver arquivo

@@ -70,7 +70,7 @@
if (isAuthenticator(type)) {
console.log('submitVerification: sending authenticator code: '+code);
this.sendAuthenticatorCode({
uuid: this.username,
userId: this.username,
code: code,
verifyOnly: false,
messages: this.messages,


Carregando…
Cancelar
Salvar