Files
skyline-console/src/stores/nova/instance.js
xusongfu 81c037de41 feat: Add tags to nova service and so on
1.Lists tags, creates, replaces tags for a server
2.Fix input autocomplete in Chrome browser
3.Fix some e2e test bugs

Change-Id: I6236da8670d36c88978317d34a50cde3974b83d9
2022-03-26 20:11:15 +08:00

461 lines
10 KiB
JavaScript

// Copyright 2021 99cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { action, observable } from 'mobx';
import { get } from 'lodash';
import client from 'client';
import Base from 'stores/base';
import { RecycleBinStore } from '../skyline/recycle-server';
export class ServerStore extends Base {
@observable
interface = {};
@observable
securityGroups = {};
@observable
interfaces = [];
@observable
serverSnapshots = [];
get client() {
return client.nova.servers;
}
get imageClient() {
return client.glance.images;
}
get portClient() {
return client.neutron.ports;
}
get networkClient() {
return client.neutron.networks;
}
get sgClient() {
return client.neutron.securityGroups;
}
get mapper() {
return (item) => {
item.status = item.status.toLowerCase();
if (!item.flavor_info) {
item.flavor_info = item.flavor;
}
return item;
};
}
listFetchByClient(params) {
return this.skylineClient.extension.servers(params);
}
get paramsFuncPage() {
return (params) => {
const { current, noReminder, ...rest } = params;
return rest;
};
}
updateParamsSortPage = (params, sortKey, sortOrder) => {
if (sortKey && sortOrder) {
params.sort_keys = sortKey;
params.sort_dirs = sortOrder === 'descend' ? 'desc' : 'asc';
}
};
@action
async fetchDetailWithoutExpiration({ id, all_projects }) {
this.isLoading = true;
const result = await this.client.show(
id,
this.getDetailParams({ all_projects })
);
const originData = get(result, this.responseKey) || result;
this.detail = this.mapperBeforeFetchProject(originData);
this.isLoading = false;
return this.detail;
}
async detailDidFetch(item, all_projects, filters) {
const { id } = item;
const { isRecycleBinDetail } = filters;
try {
if (!isRecycleBinDetail) {
const result = await this.fetchList({
uuid: id,
noReminder: true,
all_projects,
});
item.itemInList = result[0];
} else {
const store = new RecycleBinStore();
const result = await store.fetchList({ uuid: id, all_projects });
item.itemInList = result[0];
}
} catch (e) {
// eslint-disable-next-line no-console
console.log(e);
}
return item;
}
async requestList(params, originParams = {}) {
const { members, isServerGroup } = originParams;
if (members && isServerGroup && members.length === 0) {
return [];
}
const data = !this.fetchListByLimit
? await this.requestListAll(params)
: await this.requestListAllByLimit(params, 100);
return data;
}
async listDidFetch(newData, allProjects, filters) {
if (newData.length === 0) {
return newData;
}
const { members, isServerGroup, host } = filters;
const isoImages = await this.imageClient.list({ disk_format: 'iso' });
const { images } = isoImages;
if (images[0]) {
const imageId = images.map((it) => it.id);
newData.map((server) => {
if (imageId.indexOf(server.image) !== -1) {
server.iso_server = true;
}
return server;
});
}
if (isServerGroup) {
return newData.filter((it) => members.indexOf(it.id) >= 0);
}
if (host) {
return newData.filter((it) => it.host === host);
}
return newData.map((it) => ({
...it,
tags: (it.origin_data || {}).tags || [],
}));
}
@action
async fetchInterface({ id }) {
this.interface.isLoading = true;
const params = { device_id: id };
const [resData, networks] = await Promise.all([
this.portClient.list(params),
this.networkClient.list(),
]);
const interfaces = resData.ports;
const interfaceAll = [];
networks.networks.forEach((network) => {
const interfaceItem = [];
interfaces.forEach((it) => {
if (it.network_id === network.id) {
it.network_name = network.name;
interfaceItem.push(it);
}
});
if (interfaceItem.length !== 0) {
interfaceAll.push(interfaceItem);
}
});
this.interface = {
data: interfaceAll || [],
total: resData.total_count || resData.length || 0,
isLoading: false,
};
}
@action
async fetchSecurityGroup({ id }) {
this.securityGroups.isLoading = true;
const portResult = await this.portClient.list({
device_id: id,
});
const { ports = [] } = portResult;
const sgs = [];
ports.forEach((it) => sgs.push(...it.security_groups));
const sgIds = Array.from(new Set(sgs));
let sgItems = [];
try {
const result = await Promise.all(
sgIds.map((it) => this.sgClient.show(it))
);
sgItems = result.map((it) => it.security_group);
} catch (e) {}
this.securityGroups = {
data: sgItems || [],
interfaces: ports,
isLoading: false,
};
}
@action
delete = async ({ id }) => {
return this.client.delete(id);
};
@action
async create(body) {
return this.submitting(this.client.create(body));
}
@action
async getConsole({ id }) {
const body = {
remote_console: {
protocol: 'vnc',
type: 'novnc',
},
};
const result = await this.client.createConsole(id, body);
this.isSubmitting = false;
return result;
}
@action
async getConsoleIronic({ id }) {
const body = {
remote_console: {
protocol: 'serial',
type: 'serial',
},
};
const result = await this.client.createConsole(id, body);
this.isSubmitting = false;
return result;
}
@action
update(id, body) {
return this.submitting(this.client.action(id, body));
}
@action
async operation({ body, id, key }) {
// set timeout to delay to fresh
let reqBody = body;
if (!reqBody) {
reqBody = {};
reqBody[key] = null;
}
return this.update(id, reqBody);
}
@action
async lock({ id }) {
return this.operation({ key: 'lock', id });
}
@action
async unlock({ id }) {
return this.operation({ key: 'unlock', id });
}
@action
async pause({ id }) {
return this.operation({ key: 'pause', id });
}
@action
async unpause({ id }) {
return this.operation({ key: 'unpause', id });
}
@action
async suspend({ id }) {
return this.operation({ key: 'suspend', id });
}
@action
async resume({ id }) {
return this.operation({ key: 'resume', id });
}
@action
async start({ id }) {
return this.operation({ key: 'os-start', id });
}
@action
async stop({ id }) {
return this.operation({ key: 'os-stop', id });
}
@action
async restore({ id }) {
return this.operation({ key: 'restore', id });
}
@action
async forceDelete({ id }) {
const body = {
forceDelete: null,
};
return this.client.action(id, body);
}
@action
async softReboot({ id }) {
const body = {
reboot: {
type: 'SOFT',
},
};
return this.operation({ body, id });
}
@action
async reboot({ id }) {
const body = {
reboot: {
type: 'HARD',
},
};
return this.operation({ body, id });
}
@action
async changePassword({ id, password }) {
const body = {
changePassword: {
adminPass: password,
},
};
return this.operation({ body, id });
}
@action
async createImage({ id, image }) {
const body = {
createImage: {
name: image,
metadata: {
usage_type: 'common',
},
},
};
return this.operation({ body, id });
}
@action
async rebuild({ id, image }) {
const body = {
rebuild: {
imageRef: image,
},
};
return this.operation({ body, id });
}
@action
async resize({ id, flavor }) {
const body = {
resize: {
flavorRef: flavor,
},
};
return this.operation({ body, id });
}
@action
async liveResize({ id, flavor }) {
const body = {
liveResize: {
flavorRef: flavor,
},
};
return this.operation({ body, id });
}
@action
async migrate({ id, body }) {
if (body) {
const newBody = {
migrate: body,
};
return this.operation({ body: newBody, id });
}
return this.operation({ key: 'migrate', id });
}
@action
async shelve({ id }) {
return this.operation({ key: 'shelve', id });
}
@action
async unshelve({ id }) {
return this.operation({ key: 'unshelve', id });
}
@action
async migrateLive({ id, body }) {
const newBody = {
'os-migrateLive': body,
};
return this.operation({ body: newBody, id });
}
@action
async removeFloatingIp({ id, body }) {
const newBody = {
removeFloatingIp: body,
};
return this.operation({ body: newBody, id });
}
@action
async addInterface({ id, body }) {
return this.submitting(this.client.interfaces.create(id, body));
}
@action
async fetchInterfaceList({ id }) {
const result = await this.client.interfaces.list(id);
this.interfaces = result.interfaceAttachments;
return result.interfaceAttachments;
}
@action
async detachInterface({ id, ports }) {
return this.submitting(
Promise.all(ports.map((port) => this.client.interfaces.delete(id, port)))
);
}
@action
async attachVolume({ id, body }) {
return this.submitting(this.client.volumeAttachments.create(id, body));
}
@action
async detachVolume({ id, volumes }) {
return this.submitting(
Promise.all(
volumes.map((item) => this.client.volumeAttachments.delete(id, item))
)
);
}
}
const globalServerStore = new ServerStore();
export default globalServerStore;