feat: Add initial code of skyline-console

Add initial code of skyline-console

Change-Id: Icba2152a014761f53789357b5085d0779cd0e2a4
This commit is contained in:
Hanxiang Gao 2021-06-01 23:26:19 +08:00
parent e022d711a1
commit 4eb68e7fb2
1022 changed files with 125638 additions and 0 deletions

66
.babelrc Normal file
View File

@ -0,0 +1,66 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"esmodules": true
}
}
],
"@babel/preset-react"
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": {
"version": 3,
"proposals": true
}
}
],
"@babel/plugin-transform-modules-commonjs",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-throw-expressions",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"react-hot-loader/babel",
[
"import",
{
"libraryName": "antd",
"libraryDirectory": "lib",
"style": true
},
"antd"
],
[
"import",
{
"libraryName": "@ant-design/icons",
"libraryDirectory": "lib/icons",
"camel2DashComponentName": false
},
"@ant-design/icons"
]
],
"env": {
"test": {
"plugins": [
[
"istanbul",
{
"useInlineSourceMaps": false
}
]
]
}
}
}

13
.dockerignore Normal file
View File

@ -0,0 +1,13 @@
npm-debug.log
yarn-error.log
node_modules
package-lock.json
.git/
.idea/
.vscode/
run/
.DS_Store
*.sw*
*.un~

4
.eslintignore Normal file
View File

@ -0,0 +1,4 @@
dist
node_modules
coverage
test/e2e/report

77
.eslintrc Normal file
View File

@ -0,0 +1,77 @@
{
"extends": ["airbnb", "plugin:prettier/recommended"],
"parser": "babel-eslint",
"plugins": ["cypress"],
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,
"modules": true,
"legacyDecorators": true
}
},
"env": {
"es6": true,
"commonjs": true,
"browser": true,
"jest": true,
"cypress/globals": true
},
"settings": {
"import/resolver": {
"alias": {
"map": [
["@", "./src"],
["src", "./src"],
["image", "./src/asset/image"],
["components", "./src/components"],
["utils", "./src/utils"],
["stores", "./src/stores"],
["pages", "./src/pages"],
["containers", "./src/containers"],
["layouts", "./src/layouts"],
["client", "./src/client"],
["resources", "./src/resources"],
["core", "./src/core"]
],
"extensions": [".js", ".jsx"]
}
}
},
"rules": {
"camelcase": "warn",
"react/prop-types": "warn",
"class-methods-use-this": "off",
"react/prefer-stateless-function": "warn",
"no-plusplus": "warn",
"no-param-reassign": "warn",
"react/jsx-props-no-spreading": "warn",
"react/static-property-placement": "warn",
"prefer-destructuring": "warn",
"no-use-before-define": "warn",
"react/forbid-prop-types": "warn",
"react/no-array-index-key": "warn",
"react/require-default-props": "warn",
"consistent-return": "warn",
"no-underscore-dangle": "warn",
"no-unused-expressions": "warn",
"import/no-cycle": "warn",
"no-empty": [
2,
{
"allowEmptyCatch": true
}
],
"react/destructuring-assignment": "warn",
"jsx-a11y/click-events-have-key-events": "warn",
"jsx-a11y/no-static-element-interactions": "warn",
"import/no-extraneous-dependencies": "warn",
"import/prefer-default-export": "warn",
"no-nested-ternary": "warn",
},
"globals": {
"t": true,
"globals": true,
"request": true
}
}

29
.gitignore vendored Normal file
View File

@ -0,0 +1,29 @@
/node_modules/
/dist
.DS_Store
yarn-error.log
package-lock.json
docs/
.vscode
test/e2e/videos
test/e2e/screenshots
test/e2e/downloads
.nyc_output
coverage
test/e2e/results
test/e2e/report
*.qcow2
# config
test/e2e/config/local_config.yaml
# Python
__pycache__/
*.py[cod]
*$py.class
.env
.venv
env/
venv/
ENV/
/skyline_console/static

3
.prettierignore Normal file
View File

@ -0,0 +1,3 @@
dist
node_modules
coverage

5
.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
}

57
Gruntfile.js Normal file
View File

@ -0,0 +1,57 @@
// 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.
module.exports = function (grunt) {
grunt.initConfig({
i18next: {
dev: {
src: ['src/**/*.{jsx,js}'],
dest: 'src',
options: {
lngs: ['en', 'zh'],
removeUnusedKeys: true,
sort: true,
keySeparator: false,
nsSeparator: false,
interpolation: {
prefix: '{{',
suffix: '}}',
},
resource: {
// loadPath: 'src/locales/{{lng}}/{{ns}}.json',
loadPath: 'src/locales/{{lng}}.json',
// savePath: 'locales/{{lng}}/{{ns}}.json'
savePath: 'locales/{{lng}}.json',
},
func: {
list: ['t', 't.html'],
extensions: ['.js', '.jsx'],
},
defaultValue: (lng, ns, key) => {
if (lng === 'zh') {
return '';
}
return key;
},
},
},
},
});
// Load the plugin that provides the "i18next" task.
grunt.loadNpmTasks('i18next-scanner');
// Default task(s).
grunt.registerTask('default', ['i18next']);
};

177
LICENSE Normal file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

83
Makefile Normal file
View File

@ -0,0 +1,83 @@
SOURCES := src
ROOT_DIR ?= $(shell git rev-parse --show-toplevel)
# Color
no_color = \033[0m
black = \033[0;30m
red = \033[0;31m
green = \033[0;32m
yellow = \033[0;33m
blue = \033[0;34m
purple = \033[0;35m
cyan = \033[0;36m
white = \033[0;37m
# Params
MODE ?= prod
BUILD_ENGINE ?= docker
# Version
RELEASE_VERSION ?= $(shell git rev-parse --short HEAD)_$(shell date -u +%Y-%m-%dT%H:%M:%S%z)
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
GIT_COMMIT ?= $(shell git rev-parse --verify HEAD)
.PHONY: help
help:
@echo "Skyline console development makefile"
@echo
@echo "Usage: make <TARGET>"
@echo
@echo "Target:"
@echo " git_config Initialize git configuration."
@echo " install Installs the project dependencies."
@echo " build Build source and wheel packages."
@echo " lint Check JavaScript code."
@echo " test Run unit tests."
@echo
.PHONY: git_config
user_name = $(shell git config --get user.name)
user_email = $(shell git config --get user.email)
commit_template = $(shell git config --get commit.template)
git_config:
ifeq ($(user_name),)
@printf "$(cyan)\n"
@read -p "Set your git user name: " user_name; \
git config --local user.name $$user_name; \
printf "$(green)User name was set.\n$(cyan)"
endif
ifeq ($(user_email),)
@printf "$(cyan)\n"
@read -p "Set your git email address: " user_email; \
git config --local user.email $$user_email; \
printf "$(green)User email address was set.\n$(no_color)"
endif
ifeq ($(commit_template),)
@git config --local commit.template $(ROOT_DIR)/tools/git_config/commit_message.txt
endif
@printf "$(green)Project git config was successfully set.\n$(no_color)"
@printf "${yellow}You may need to run 'pip install git-review' install git review tools.\n\n${no_color}"
.PHONY: install
install:
yarn install
.PHONY: build
build:
rm -rf $(ROOT_DIR)/skyline_console/static
yarn run build
poetry build
.PHONY: lint
lint:
yarn run lint
.PHONY: test
test:
yarn run test:unit

63
README.md Normal file
View File

@ -0,0 +1,63 @@
# 使用说明
简体中文 | [English](./en.md)
## 环境依赖
- `node`: lts/erbium (v12.\*)
- `yarn`: 1.22.4 +
## 本地环境搭建
以 CentOS 为例
- 安装 nvm (nodejs 版本管理工具)
```shell
wget -P /root/ --tries=10 --retry-connrefused --waitretry=60 --no-dns-cache --no-cache https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh
bash /root/install.sh
. /root/.nvm/nvm.sh
```
- 安装 nodejs
```shell
NODE_VERSION=erbium
nvm install --lts=$NODE_VERSION
nvm alias default lts/$NODE_VERSION
nvm use default
```
- 验证 nodejs 和 npm 版本
```shell
node -v
# v12.*.*
npm -v
# 6.*.*
```
- 安装 yarn
```shell
npm install -g yarn
```
- 安装项目依赖
在项目根目录下,`package.json`同级。
```shell
yarn install
```
等待安装完成即可。
## 开发使用方法
在项目根目录下,`package.json`同级。
- `yarn run mock`: 使用[rap2](http://rap2.taobao.org/)工具 mock 接口
- `yarn run dev`: 使用实际接口,需要将`webpack.dev.js`文件第 27 行的 "http://pre.xxx.com"
修改为实际地址
- `yarn run build`: 构建打包,可将生成的 dist 目录的内容交给后端

27
config/theme.js Normal file
View File

@ -0,0 +1,27 @@
// 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.
module.exports = {
'primary-color': '#0068FF',
'link-color': '#0068FF',
// 'link-hover-color': '#005ADE',
// 'link-active-color': '005ADE',
'success-color': '#57E39B',
'warning-color': '#979797',
'error-color': '#EB354D',
'btn-default-color': '#0068FF',
'btn-default-border': '#0068FF',
'border-radius-base': '4px',
'font-size-base': '12px',
};

142
config/webpack.common.js Normal file
View File

@ -0,0 +1,142 @@
// 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.
const webpack = require('webpack');
const { normalize, resolve } = require('path');
// const path = require("path");
// const CleanWebpackPlugin = require('clean-webpack-plugin');
const HappyPack = require('happypack');
const os = require('os');
const moment = require('moment');
const root = (path) => resolve(__dirname, `../${path}`);
const version = moment().unix();
module.exports = {
module: {
rules: [
{
test: /\.jsx?$/,
include: [root('src'), root('common')],
use: 'happypack/loader?id=jsx',
},
{
test: /\.jsx?$/,
include: root('node_modules'),
use: 'cache-loader',
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.(png|gif|jpg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10240,
name: normalize(`asset/image/[name].${version}.[ext]`),
},
},
],
exclude: [
root('src/asset/image/logo.png'),
root('src/asset/image/loginRightLogo.png'),
],
},
{
test: /\.(png|gif|jpg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: false,
name: normalize('asset/image/[name].[ext]'),
},
},
],
include: [
root('src/asset/image/logo.png'),
root('src/asset/image/loginRightLogo.png'),
],
},
{
test: /\.svg$/,
use: [
{
loader: 'url-loader',
options: {
limit: false,
name: normalize('asset/image/[name].[ext]'),
},
},
],
include: [
root('src/asset/image/logo-small.svg'),
root('src/asset/image/logo-extend.svg'),
],
},
{
test: /\.(woff|woff2|ttf|eot|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10240,
name: normalize(`asset/image/[name].${version}.[ext]`),
},
},
],
exclude: [
root('src/asset/image/logo-small.svg'),
root('src/asset/image/logo-extend.svg'),
],
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
modules: [root('src'), root('src/pages'), 'node_modules'],
alias: {
'@': root('src'),
src: root('src'),
asset: root('src/asset'),
image: root('src/asset/image'),
core: root('src/core'),
containers: root('src/containers'),
layouts: root('src/layouts'),
components: root('src/components'),
pages: root('src/pages'),
utils: root('src/utils'),
stores: root('src/stores'),
locales: root('src/locales'),
styles: root('src/styles'),
resources: root('src/resources'),
},
},
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new HappyPack({
threads: os.cpus().length - 1,
id: 'jsx',
loaders: ['babel-loader?cacheDirectory'],
}),
],
};
module.exports.version = version;

150
config/webpack.dev.js Normal file
View File

@ -0,0 +1,150 @@
// 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.
const { resolve } = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
const common = require('./webpack.common');
const theme = require('./theme');
// const OpenBrowserPlugin = require('open-browser-webpack-plugin');
const root = (path) => resolve(__dirname, `../${path}`);
module.exports = (env) => {
const API = (env || {}).API || 'mock';
console.log('API %s', API);
const devServer = {
host: '0.0.0.0',
// host: 'localhost',
port: 8088,
contentBase: root('dist'),
historyApiFallback: true,
compress: true,
hot: true,
inline: true,
disableHostCheck: true,
// progress: true
};
if (API === 'mock' || API === 'dev') {
devServer.proxy = {
'/api': {
target: 'http://localhost',
changeOrigin: true,
secure: false,
},
};
}
const { version, ...restConfig } = common;
return merge(restConfig, {
entry: {
main: root('src/core/index.jsx'),
},
output: {
filename: '[name].js',
path: root('dist'),
publicPath: '/',
},
mode: 'development',
devtool: 'inline-source-map',
devServer,
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /\.(css|less)$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
options: {
modules: {
mode: 'global',
},
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
{
loader: 'postcss-loader',
options: {
plugins: [autoprefixer('last 2 version')],
sourceMap: true,
},
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
importLoaders: true,
javascriptEnabled: true,
},
},
],
},
{
test: /\.(less)$/,
include: /node_modules/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
javascriptEnabled: true,
modifyVars: theme,
},
},
],
},
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// new OpenBrowserPlugin({
// url: 'http://localhost:8080',
// browser: "Google Chrome",
// }),
new webpack.DefinePlugin({
// 为项目注入环境变量
'process.env.API': JSON.stringify(API),
}),
new HtmlWebPackPlugin({
template: root('src/asset/template/index.html'),
favicon: root('src/asset/image/favicon.ico'),
}),
],
});
};

175
config/webpack.e2e.js Normal file
View File

@ -0,0 +1,175 @@
// 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.
const { resolve } = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const HtmlWebPackPlugin = require('html-webpack-plugin');
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const autoprefixer = require('autoprefixer');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const common = require('./webpack.common');
const theme = require('./theme');
const root = (path) => resolve(__dirname, `../${path}`);
const { version, ...restConfig } = common;
module.exports = (env) => {
const API = (env || {}).API || 'mock';
// const devServer = {
// // host: '0.0.0.0',
// host: 'localhost',
// port: 8088,
// contentBase: root('dist'),
// historyApiFallback: true,
// compress: true,
// hot: false,
// inline: false,
// disableHostCheck: true,
// // progress: true
// };
return merge(restConfig, {
entry: {
main: root('src/core/index.jsx'),
},
output: {
filename: '[name].js',
path: root('dist'),
publicPath: '/',
chunkFilename: `[name].bundle.${version}.js`,
},
mode: 'production',
// devtool: 'inline-source-map',
// devServer: devServer,
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /\.(css|less)$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
options: {
modules: {
mode: 'global',
},
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
{
loader: 'postcss-loader',
options: {
plugins: [autoprefixer('last 2 version')],
sourceMap: false,
},
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
importLoaders: true,
javascriptEnabled: true,
},
},
],
},
{
test: /\.(less)$/,
include: /node_modules/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
javascriptEnabled: true,
modifyVars: theme,
},
},
],
},
],
},
plugins: [
new webpack.DefinePlugin({
// 为项目注入环境变量
'process.env.API': JSON.stringify(API),
}),
new HtmlWebPackPlugin({
template: root('src/asset/template/index.html'),
favicon: root('src/asset/image/favicon.ico'),
}),
new CleanWebpackPlugin(['dist'], {
root: resolve(__dirname, `../`),
}),
// new BundleAnalyzerPlugin(),
],
optimization: {
splitChunks: {
maxInitialRequests: 10,
cacheGroups: {
commons: {
chunks: 'all',
name: 'common',
minChunks: 1,
minSize: 0,
},
vendor: {
test: /node_modules/,
chunks: 'all',
name: 'vendor',
minChunks: 1,
priority: 10,
enforce: true,
},
},
},
runtimeChunk: {
name: () => `runtime.${version}`,
},
minimize: true, // default true for production
minimizer: [
new TerserPlugin({
sourceMap: false,
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
},
});
};

174
config/webpack.prod.js Normal file
View File

@ -0,0 +1,174 @@
// 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.
const { resolve } = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const HtmlWebPackPlugin = require('html-webpack-plugin');
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const autoprefixer = require('autoprefixer');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const common = require('./webpack.common');
const theme = require('./theme');
const root = (path) => resolve(__dirname, `../${path}`);
const { version, ...restConfig } = common;
module.exports = (env) => {
const API = (env || {}).API || 'mock';
return merge(restConfig, {
entry: {
main: root('src/core/index.jsx'),
},
output: {
filename: '[name].js',
path: root('skyline_console/static'),
publicPath: '/',
chunkFilename: `[name].bundle.${version}.js`,
},
mode: 'production',
// devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /\.(css|less)$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
options: {
modules: {
mode: 'global',
},
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
{
loader: 'postcss-loader',
options: {
plugins: [autoprefixer('last 2 version')],
sourceMap: false,
},
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
importLoaders: true,
javascriptEnabled: true,
},
},
],
},
{
test: /\.(less)$/,
include: /node_modules/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
javascriptEnabled: true,
modifyVars: theme,
},
},
],
},
],
},
plugins: [
// 热更新没必要。
// new webpack.HotModuleReplacementPlugin(),
// new OpenBrowserPlugin({
// url: 'http://localhost:8080',
// browser: "Google Chrome",
// }),
new webpack.DefinePlugin({
// 为项目注入环境变量
'process.env.API': JSON.stringify(API),
}),
new HtmlWebPackPlugin({
template: root('src/asset/template/index.html'),
favicon: root('src/asset/image/favicon.ico'),
}),
new CleanWebpackPlugin(['dist'], {
root: resolve(__dirname, `../`),
}),
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /\.js$/,
threshold: 10240,
minRatio: 0.8,
}),
// new BundleAnalyzerPlugin(),
],
optimization: {
splitChunks: {
maxInitialRequests: 10,
cacheGroups: {
commons: {
chunks: 'async',
name: 'common',
minChunks: 2,
minSize: 0,
},
vendor: {
test: /node_modules/,
chunks: 'async',
name: 'vendor',
priority: 10,
enforce: true,
},
},
},
runtimeChunk: {
name: () => `runtime.${version}`,
},
minimize: true, // default true for production
minimizer: [
new TerserPlugin({
extractComments: false,
sourceMap: false,
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
},
});
};

28
cypress.json Normal file
View File

@ -0,0 +1,28 @@
{
"baseUrl": "http://localhost:8081",
"viewportWidth": 1600,
"viewportHeight": 900,
"video": false,
"env": {
"username": "administrator",
"password": "passw0rd",
"region": "RegionOne",
"domain": "Default",
"sessionKey": "X-Auth-Token",
"language": "en"
},
"reporter": "mochawesome",
"reporterOptions": {
"reportDir": "test/e2e/results",
"overwrite": false,
"html": false,
"json": true
},
"fixturesFolder": "test/e2e/fixtures",
"integrationFolder": "test/e2e/integration",
"pluginsFile": "test/e2e/plugins/index.js",
"screenshotsFolder": "test/e2e/screenshots",
"videosFolder": "test/e2e/videos",
"supportFile": "test/e2e/support/index.js",
"downloadsFolder": "test/e2e/downloads"
}

36
jest.config.js Normal file
View File

@ -0,0 +1,36 @@
// 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.
module.exports = {
bail: true,
transformIgnorePatterns: ['<rootDir>/node_modules/'],
transform: {
'^.+\\.(js|jsx)$': 'babel-jest',
},
moduleNameMapper: {
'.+\\.(css|styl|less|sass|scss)$': 'identity-obj-proxy',
'\\.svg': '<rootDir>/test/unit/svg-mock.js',
'^@/(.*)$': '<rootDir>/src/$1',
'^src(.*)$': '<rootDir>/src$1',
'^components(.*)$': '<rootDir>/src/components$1',
'^layouts(.*)$': '<rootDir>/src/layouts$1',
'^stores(.*)$': '<rootDir>/src/stores$1',
'^utils(.*)$': '<rootDir>/src/utils$1',
'^pages(.*)$': '<rootDir>/src/pages$1',
},
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
moduleDirectories: ['node_modules', 'src'],
testPathIgnorePatterns: ['node_modules', '.cache', 'test/e2e', 'config'],
setupFiles: ['<rootDir>/test/unit/setup-tests.js'],
};

24
jsconfig.json Normal file
View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"jsx": "react",
"baseUrl": ".",
"experimentalDecorators": true,
"paths": {
"@/*": ["./src/*"],
"src/*": ["./src/*"],
"asset/*": ["./src/asset/*"],
"image/*": ["./src/asset/image/*"],
"core/*": ["./src/core/*"],
"containers/*": ["./src/containers/*"],
"layouts/*": ["./src/layouts/*"],
"components/*": ["./src/components/*"],
"pages/*": ["./src/pages/*"],
"utils/*": ["./src/utils/*"],
"stores/*": ["./src/stores/*"],
"locales/*": ["./src/locales/*"],
"styles/*": ["./src/styles/*"],
"resources/*": ["./src/resources/*"]
}
},
"include": ["src/**/*"]
}

156
package.json Normal file
View File

@ -0,0 +1,156 @@
{
"name": "skyline-console",
"version": "0.1.0",
"description": "",
"author": "OpenStack <openstack-discuss@lists.openstack.org>",
"license": "Apache 2.0",
"scripts": {
"mock": "webpack-dev-server --open --config config/webpack.dev.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --config config/webpack.dev.js --env.API=dev",
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=2048 webpack --progress --config config/webpack.prod.js",
"build:win": "set NODE_OPTIONS=--max-old-space-size=2048 && webpack --progress --config config/webpack.prod.js",
"build:test": "cross-env NODE_ENV=test NODE_OPTIONS=--max-old-space-size=2048 webpack --progress --config config/webpack.e2e.js",
"i18n": "grunt",
"lint": "eslint src --fix --quiet --ext .js,.jsx",
"lint:test": "eslint test --fix --quiet --ext .js",
"report:delete-json": "rm -rf test/e2e/results/* || true",
"report:delete-html": "rm -rf test/e2e/report || true",
"report:pre": "npm run report:delete-json && npm run report:delete-html && mkdir test/e2e/report",
"report:merge": "npx mochawesome-merge test/e2e/results/*.json > test/e2e/report/merge-report.json",
"report:generate": "npm run report:merge && npx mochawesome-report-generator test/e2e/report/merge-report.json -o test/e2e/report",
"test:e2e:run": "npm run report:pre && cypress run || true",
"test:e2e": "npm run test:e2e:run && npm run report:generate",
"test:e2e:open": "cypress open",
"test:e2e:server": "cross-env NODE_ENV=test webpack-dev-server --open --progress --config config/webpack.e2e.js",
"test:unit": "cross-env NODE_ENV=development jest",
"test:unit:coverage": "cross-env NODE_ENV=development jest --coverage"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,jsx}": [
"eslint --fix",
"git add"
],
"*.{html,css,scss,md,json}": [
"prettier --write",
"git add"
]
},
"dependencies": {
"@ant-design/icons": "^4.0.6",
"@antv/data-set": "^0.11.4",
"@antv/g6": "^3.5.10",
"@babel/runtime-corejs3": "^7.14.0",
"ace-builds": "^1.4.12",
"antd": "^4.1.3",
"array-move": "3.0.1",
"axios": "^0.21.1",
"bizcharts": "^4.0.6",
"cache-loader": "^4.1.0",
"cidr-regex": "^3.1.1",
"classnames": "^2.2.6",
"cookie": "^0.4.1",
"escape-html": "^1.0.3",
"eslint-plugin-babel": "^5.3.1",
"file-saver": "^2.0.2",
"history": "4.7.2",
"intersection-observer": "^0.11.0",
"intl-messageformat": "7.8.4",
"invariant": "^2.2.4",
"ip-address": "^7.1.0",
"js-yaml": "^4.0.0",
"json2csv": "^5.0.1",
"lodash": "^4.17.19",
"mobx": "^5.1.0",
"mobx-react": "^5.2.8",
"mobx-react-router": "^4.1.0",
"moment": "^2.24.0",
"nanoid": "^3.0.2",
"promise-polyfill": "^8.1.3",
"prop-types": "^15.7.2",
"qs": "^6.9.4",
"react": "^16.2.0",
"react-ace": "^9.2.0",
"react-document-title": "^2.0.3",
"react-dom": "^16.2.0",
"react-fast-compare": "^3.0.1",
"react-highcharts": "^16.0.2",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-sortable-hoc": "1.11.0"
},
"devDependencies": {
"@babel/core": "^7.14.3",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-proposal-decorators": "^7.14.2",
"@babel/plugin-proposal-throw-expressions": "^7.12.13",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-transform-modules-commonjs": "^7.14.0",
"@babel/plugin-transform-runtime": "^7.14.3",
"@babel/preset-env": "^7.14.2",
"@babel/preset-react": "^7.13.13",
"@cypress/code-coverage": "^3.9.5",
"autoprefixer": "^9.3.1",
"babel-eslint": "^9.0.0",
"babel-jest": "^26.6.3",
"babel-loader": "^8.1.0",
"babel-plugin-import": "^1.8.0",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-react-css-modules": "^3.4.2",
"clean-webpack-plugin": "^1.0.0",
"compression-webpack-plugin": "5.0.1",
"cross-env": "^7.0.3",
"css-loader": "^0.28.11",
"cypress": "6.8.0",
"cypress-file-upload": "^5.0.6",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.6",
"eslint": "^7.2.0",
"eslint-config-airbnb": "18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-cypress": "^2.11.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^1.7.0",
"file-loader": "^6.0.0",
"grunt": "^1.2.1",
"happypack": "^5.0.1",
"html-webpack-plugin": "^3.1.0",
"husky": "^1.0.0-rc.14",
"i18next-scanner": "2.9.2",
"identity-obj-proxy": "^3.0.0",
"istanbul-lib-coverage": "^3.0.0",
"jest": "^26.6.3",
"jest-enzyme": "^7.1.2",
"less": "^3.8.1",
"less-loader": "^4.1.0",
"lint-staged": "^11.0.0",
"mochawesome": "^6.2.2",
"mochawesome-merge": "^4.2.0",
"mochawesome-report-generator": "^5.2.0",
"postcss-less": "^2.0.0",
"postcss-loader": "^3.0.0",
"prettier": "^2.3.0",
"react-css-modules": "^4.7.7",
"react-hot-loader": "^4.12.20",
"style-loader": "^0.20.3",
"terser-webpack-plugin": "4.2.3",
"url-loader": "^4.1.1",
"webpack": "^4.42.1",
"webpack-cli": "3.3.0",
"webpack-dev-server": "^3.1.10",
"webpack-merge": "^4.1.4"
},
"engines": {
"node": ">=10.22.0",
"yarn": ">=1.22.4"
}
}

8
poetry.lock generated Normal file
View File

@ -0,0 +1,8 @@
package = []
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]

10
pyproject.toml Normal file
View File

@ -0,0 +1,10 @@
[tool.poetry]
name = "skyline-console"
version = "0.1.0"
description = ""
authors = ["OpenStack <openstack-discuss@lists.openstack.org>"]
include = ["skyline_console/static/**/*"]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

View File

@ -0,0 +1 @@
__version__ = "0.1.0"

View File

@ -0,0 +1,12 @@
import sys
from pathlib import Path
import skyline_console
static_path = Path(skyline_console.__file__).parent.joinpath("static")
if static_path.joinpath("index.html").exists():
print(f'Static resource directory of "skyline-console" is:\n{str(static_path)}')
else:
print('Error, "skyline-console" doesn\'t contain any static resources')
sys.exit(1)

47
src/api/cinder/backup.js Normal file
View File

@ -0,0 +1,47 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Create a restore on backup
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} backupId The UUID of the backupchains.
* @param {Object} data request body
* @param {Object} data.restore The restore object.
* @returns {Promise}
*/
export const createBackupRestoreOnCinder = (projectId, backupId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/backups/${backupId}/restore`),
data,
});
/**
* Create a restore on backup chain
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} backupId The UUID of the backupchains.
* @param {Object} data request body
* @param {Object} data.restore The restore object.
* @returns {Promise}
*/
export const createBackupChainRestoreOnCinder = (projectId, backupId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/backup_chains/${backupId}/restore`),
data,
});

23
src/api/cinder/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { cinderBase } from 'utils/constants';
const getCinderBaseUrl = (key) => `${cinderBase()}/${key}`;
export default getCinderBaseUrl;

View File

@ -0,0 +1,31 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Show quota usage for a project
* @param {String} adminProjectId The UUID of the administrative project.
* @param {Object} params request query
* @param {Boolean} params.usage Default : false
* @returns {Promise}
*/
export const fetchAvailabilityZoneOnProject = (adminProjectId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${adminProjectId}/os-availability-zone`),
params,
});

View File

@ -0,0 +1,52 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Show quota usage for a project
* @param {String} adminProjectId The UUID of the administrative project.
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} params request query
* @param {Boolean} params.usage Default : false
* @returns {Promise}
*/
export const fetchQuotaUsageOnProject = (adminProjectId, projectId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${adminProjectId}/os-quota-sets/${projectId}`),
params,
});
/**
* Update quotas for a project
* @param {String} adminProjectId The UUID of the tenant in a multi-tenancy cloud.
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} data request body
* @param {Object} data.quota_set A quota object.
* @param {String} data.quota_set.volumes The number of volumes that are allowed for each project.
* @param {Number} data.quota_set.gigabytes The size (GB) of volumes and snapshots that are allowed for each project.
* @param {Number} data.quota_set.backup_gigabytes The size (GB) of backups that are allowed for each project.
* @param {Number} data.quota_set.snapshots The number of snapshots that are allowed for each project.
* @param {Number} data.quota_set.backups The number of backups that are allowed for each project.
* @returns {Promise}
*/
export const updateCinderQuotaSets = (adminProjectId, projectId, data) =>
axios.request({
method: 'put',
url: cinderBase(`${adminProjectId}/os-quota-sets/${projectId}`),
data,
});

View File

@ -0,0 +1,54 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Cinder Service change
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} actionName Actions name Avaliable Values : disable,disable-log-reason,enable,get-log,set-log,freeze,thaw,failover_host
* @param {Object} data request body
* @param {String} data.host The name of the host, when actionName is disable
* @param {String} data.binary The binary name of the service, when actionName is disable
* @param {String} data.disabled_reason The reason for disabling a service.
* @param {String} data.server The name of the host.
* @param {String} data.prefix The prefix for the log path we are querying, for example cinder. or sqlalchemy.engine
* @param {String} data.levels The log level to set, case insensitive, accepted values are INFO, WARNING, ERROR and DEBUG.
* @param {String} data.backend_id ID of backend to failover to. Default is None.
* @param {String} data.cluster The cluster name. Only in cinder-volume service.New in version 3.7
* @returns {Promise}
*/
export const toggleChangeCinderOsService = (projectId, actionName, data) =>
axios.request({
method: 'put',
url: cinderBase(`${projectId}/os-services/${actionName}`),
data,
});
/**
* List All Cinder Services
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} params request query
* @param {String} params.binary Filter the service list result by binary name of the service.
* @param {String} params.host Filter the service list result by host name of the service.
* @returns {Promise}
*/
export const fetchListCinderServices = (projectId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/os-services`),
params,
});

106
src/api/cinder/qos-specs.js Normal file
View File

@ -0,0 +1,106 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Create a QoS specification
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} data request body
* @param {Object} data.qos_specs A qos_specs object.
* @param {String} data.qos_specs.name The name of the QoS specification.
* @returns {Promise}
*/
export const createQosSpecOnCinder = (projectId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/qos-specs`),
data,
});
/**
* Set keys in a QoS specification
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} qosId The ID of the QoS specification.
* @param {Object} data request body
* @param {Object} data.qos_specs A qos_specs object.
* @returns {Promise}
*/
export const updateQosSpecOnCinder = (projectId, qosId, data) =>
axios.request({
method: 'put',
url: cinderBase(`${projectId}/qos-specs/${qosId}`),
data,
});
/**
* Unset keys in a QoS specification
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} qosId The ID of the QoS specification.
* @param {Object} data request body
* @param {Array} data.keys List of Keys.
* @returns {Promise}
*/
export const deleteKeysInQosSpecOnCinder = (projectId, qosId, data) =>
axios.request({
method: 'put',
url: cinderBase(`${projectId}/qos-specs/${qosId}`),
data,
});
/**
* Associate QoS specification with a volume type
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} qosId The ID of the QoS specification.
* @param {Object} params request query
* @param {Object} params.vol_type_id A volume type ID.
* @returns {Promise}
*/
export const fetchAssociateQosSpecOnCinder = (projectId, qosId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/qos-specs/${qosId}/associate`),
params,
});
/**
* Disassociate QoS specification from a volume type
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} qosId The ID of the QoS specification.
* @param {Object} params request query
* @param {Object} params.vol_type_id A volume type ID.
* @returns {Promise}
*/
export const fetchDisassociateQosSpecOnCinder = (projectId, qosId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/qos-specs/${qosId}/associate`),
params,
});
/**
* Show a QoS specification details
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} qosId The ID of the QoS specification.
* @param {Object} params request query
* @returns {Promise}
*/
export const fetchQosSpecDetailsOnCinder = (projectId, qosId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/qos-specs/${qosId}`),
params,
});

View File

@ -0,0 +1,62 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* List accessible snapshots
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} params request body
* @param {String} params.all_tenants Shows details for all project. Admin only.
* @param {String} params.sort A valid direction is asc (ascending) or desc (descending).
* @param {String} params.limit Default value : 10
* @param {String} params.offset Used in conjunction with limit to return a slice of items.
* @param {String} params.marker The ID of the last-seen item.
* @param {String} params.with_count Whether to show count in API response or not, default is False.
* @returns {Promise}
*/
export const fetchListAccessibleSnapshots = (projectId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/snapshots`),
params,
});
/**
* Show a snapshots details
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} snapshotId The UUID of the snapshot.
* @returns {Promise}
*/
export const fetchListAccessibleSnapshotDetails = (projectId, snapshotId) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/snapshots/${snapshotId}`),
});
/**
* Update a snapshot
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} snapshotId The UUID of the snapshot.
* @param {Object} data request body
* @returns {Promise}
*/
export const updateSnapshotOnCinder = (projectId, snapshotId, data) =>
axios.request({
method: 'put',
url: cinderBase(`${projectId}/snapshots/${snapshotId}`),
data,
});

180
src/api/cinder/types.js Normal file
View File

@ -0,0 +1,180 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Show all extra specifications for volume type
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The UUID for an existing volume type.
* @param {Object} params request query
* @returns {Promise}
*/
export const fetchExtraSpecsForTypes = (projectId, volumeTypeId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/types/${volumeTypeId}/extra_specs`),
params,
});
/**
* Create or update extra specs for volume type
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The UUID for an existing volume type.
* @param {Object} body request body
* @param {Object} body.extra_specs A set of key and value pairs that contains the specifications for a volume type.
* @returns {Promise}
*/
export const createExtraSpecsForTypes = (projectId, volumeTypeId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/types/${volumeTypeId}/extra_specs`),
data,
});
/**
* Delete extra specification for volume type
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The UUID for an existing volume type.
* @param {String} keyName The key name of the extra spec for a volume type.
* @returns {Promise}
*/
export const deleteExtraSpecsForTypes = (projectId, volumeTypeId, keyName) =>
axios.request({
method: 'delete',
url: cinderBase(
`${projectId}/types/${volumeTypeId}/extra_specs/${keyName}`
),
});
/**
* Create volume type for v2
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} data request body
* @param {Object} data.volume_type A volume_type object.
* @param {String} data.volume_type.name The name of the Volume Transfer.
* @param {String} data.volume_type.description The backup description or null.
* @param {Boolean} data.volume_type.is_public Volume type which is accessible to the public.
* @param {Object} data.volume_type.extra_specs A set of key and value pairs that contains the specifications for a volume type.
* @param {String} data.volume_type.extra_specs.capabilities example : "gpu"
* @returns {Promise}
*/
export const createVolumeType = (projectId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/types`),
data,
});
/**
* Update volume type
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The UUID for an existing volume type.
* @param {Object} data request body
* @param {Object} data.volume_type A volume_type object.
* @param {String} data.volume_type.name The name of the Volume Transfer.
* @param {String} data.volume_type.description The backup description or null.
* @param {Boolean} data.volume_type.is_public Volume type which is accessible to the public.
* @param {Object} data.volume_type.extra_specs A set of key and value pairs that contains the specifications for a volume type.
* @param {String} data.volume_type.extra_specs.capabilities example : "gpu"
* @returns {Promise}
*/
export const updateVolumeType = (projectId, volumeTypeId, data) =>
axios.request({
method: 'put',
url: cinderBase(`${projectId}/types/${volumeTypeId}`),
data,
});
/**
* Show an encryption type for v2
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The UUID for an existing volume type.
* @returns {Promise}
*/
export const fetchVolumeTypesEncryption = (projectId, volumeTypeId) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/types/${volumeTypeId}/encryption`),
});
/**
* Create an encryption type for v2
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The UUID for an existing volume type.
* @param {Object} data request body
* @param {Object} data.encryption The encryption information.
* @param {String} data.encryption.key_size Size of encryption key, in bits. For example, 128 or 256. The default value is None.
* @param {String} data.encryption.provider The class that provides encryption support.
* @param {Boolean} data.encryption.control_location The default value is front-end.
* @param {Object} data.encryption.cipher The encryption algorithm or mode. For example, aes-xts-plain64. The default value is None.
* @returns {Promise}
*/
export const createVolumeTypesEncryption = (projectId, volumeTypeId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/types/${volumeTypeId}/encryption`),
data,
});
/**
* Delete an encryption type for v2
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The UUID for an existing volume type.
* @param {String} encryptionId The ID of the encryption type.
* @returns {Promise}
*/
export const deleteVolumeTypesEncryption = (
projectId,
volumeTypeId,
encryptionId
) =>
axios.request({
method: 'delete',
url: cinderBase(
`${projectId}/types/${volumeTypeId}/encryption/${encryptionId}`
),
});
/**
* Add private volume type access
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The ID of Volume Type to be accessed by project.
* @param {Object} data request body
* @param {Object} data.addProjectAccess A addProjectAccess object. When add request
* @param {String} data.addProjectAccess.project The ID of the project. When add request
* @param {Object} data.removeProjectAccess A removeProjectAccess project. When delete request
* @param {String} data.removeProjectAccess.project The ID of the project. When delete request
* @returns {Promise}
*/
export const addOrDeleteVolumeTypeAccess = (projectId, volumeTypeId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/types/${volumeTypeId}/action`),
data,
});
/**
* List private volume type access details
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeTypeId The ID of Volume Type to be accessed by project.
* @returns {Promise}
*/
export const fetchVolumeTypesAccessDetails = (projectId, volumeTypeId) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/types/${volumeTypeId}/os-volume-type-access`),
});

View File

@ -0,0 +1,80 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Create a volume transfer
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} data request body
* @param {Object} data.transfer The volume transfer object.
* @param {String} data.transfer.name The name of the object.
* @param {String} data.transfer.volume_id The UUID of the volume.
* @param {Boolean} data.transfer.no_snapshots Transfer volume without snapshots. Defaults to False if not specified.
* @returns {Promise}
*/
export const createVolumenTransfer = (projectId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/volume-transfers`),
data,
});
/**
* List volume transfers for a project
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} params request query
* @param {Object} params.all_tenants Shows details for all project. Admin only.
* @param {String} params.limit Requests a page size of items. Returns a number of items up to a limit value.
* @param {String} params.offset Used in conjunction with limit to return a slice of items. offset is where to start in the list.
* @param {Boolean} params.marker The ID of the last-seen item.
* @param {Boolean} params.sort_key Sorts by an attribute. Default is created_at.
* @param {Boolean} params.sort_dir Sorts by one or more sets of attribute and sort direction combinations.
* @returns {Promise}
*/
export const fetchVolumenTransfersForProject = (projectId, params) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/volume-transfers`),
params,
});
/**
* Delete a volume transfer
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} transferId The unique identifier for a volume transfer.
* @returns {Promise}
*/
export const deleteVolumenTransfer = (projectId, transferId) =>
axios.request({
method: 'delete',
url: cinderBase(`${projectId}/volume-transfers/${transferId}`),
});
/**
* Accept a volume transfer
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} data request body
* @param {Object} data.accept The accept object.
* @param {String} data.accept.auth_key The name of the object.
* @returns {Promise}
*/
export const acceptVolumenTransfer = (projectId, transferId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/volume-transfers/${transferId}/accept`),
data,
});

62
src/api/cinder/volume.js Normal file
View File

@ -0,0 +1,62 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Show a volumes details
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} volumeId The UUID of the volume.
* @returns {Promise}
*/
export const fetchAccessibleVolumeDetails = (projectId, volumeId) =>
axios.request({
method: 'get',
url: cinderBase(`${projectId}/volumes/${volumeId}`),
});
/**
* Volume actions
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {Object} volumeId The UUID of the volume.
* @param {Object} data request body
* @see https://docs.openstack.org/api-ref/block-storage/v3/index.html?expanded=id356-detail#volume-transfers-volume-transfers-3-55-or-later
* @returns {Promise}
*/
export const volumeActionsOnCinder = (projectId, volumeId, data) =>
axios.request({
method: 'post',
url: cinderBase(`${projectId}/volumes/${volumeId}/action`),
data,
});
/**
* Update a volume
* @param {String} projectId The UUID of the project in a multi-tenancy cloud.
* @param {String} volumeId The UUID of the volume.
* @param {Object} data request body
* @param {Object} data.volume A volume object.
* @param {String} data.volume.description The volume description.
* @param {String} data.volume.name The volume name.
* @param {Object} data.volume.metadata One or more metadata key and value pairs that are associated with the volume.
* @returns {Promise}
*/
export const updateVolumeOnCinder = (projectId, volumeId, data) =>
axios.request({
method: 'put',
url: cinderBase(`${projectId}/volumes/${volumeId}/action`),
data,
});

23
src/api/glance/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { glanceBase } from 'utils/constants';
const getGlanceBaseUrl = (key) => `${glanceBase()}/${key}`;
export default getGlanceBaseUrl;

174
src/api/glance/images.js Normal file
View File

@ -0,0 +1,174 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Create image
* @param {Object} data request body
* @param {String} data.container_format Format of the image container.
* @param {String} data.disk_format The format of the disk.
* @param {String} data.id A unique, user-defined image UUID, in the format: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn
* @param {Number} data.min_disk Amount of disk space in GB that is required to boot the image.
* @param {Number} data.min_ram Amount of RAM in MB that is required to boot the image.
* @param {String} data.name The name of the image.
* @param {Boolean} data.protected Image protection for deletion.
* @param {Array} data.tags List of tags for this image.
* @param {String} data.visibility Visibility for this image. Valid value is one of: public, private, shared, or community.
* @returns {Promise}
*/
export const createImage = (data) =>
axios.request({
method: 'post',
url: cinderBase('images'),
data,
});
/**
* Update image
* @param {String} imageId The UUID of the image.
* @param {Object} data request body
* @param {String} data.container_format Format of the image container.
* @param {String} data.disk_format The format of the disk.
* @param {String} data.id A unique, user-defined image UUID, in the format: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn
* @param {Number} data.min_disk Amount of disk space in GB that is required to boot the image.
* @param {Number} data.min_ram Amount of RAM in MB that is required to boot the image.
* @param {String} data.name The name of the image.
* @param {Boolean} data.protected Image protection for deletion.
* @param {Array} data.tags List of tags for this image.
* @param {String} data.visibility Visibility for this image. Valid value is one of: public, private, shared, or community.
* @returns {Promise}
*/
export const updateImage = (imageId, data) =>
axios.request({
method: 'patch',
url: cinderBase(`images/${imageId}`),
headers: {
'content-type': 'application/openstack-images-v2.1-json-patch',
},
data,
});
/**
* Upload binary image data
* Set the Content-Type request header to application/octet-stream.
* @param {String} imageId The UUID of the image.
* @param {File} data Image file
* @returns {Promise}
*/
export const uploadBinaryImageData = (imageId, data) =>
axios.request({
method: 'put',
url: cinderBase(`images/${imageId}/file`),
headers: {
'content-type': 'application/octet-stream',
},
data,
});
/**
* List images
* @param {Object} params request query
* @param {Number} params.limit Requests a page size of items
* @param {String} params.disk_format Example : "iso"
* @param {String} params.marker The ID of the last-seen item.
* @param {String} params.name Filters the response by a name.
* @param {String} params.owner Filters the response by a project (also called a tenant) ID.
* @param {Boolean} params.protected Filters the response by the protected image property.
* @param {Number} params.status Filters the response by an image status.
* @param {Number} params.tag Filters the response by the specified tag value.
* @param {String} params.visibility Filters the response by an image visibility value.
* @param {Boolean} params.os_hidden When true, filters the response to display only hidden images.
* @param {String} params.member_status Filters the response by a member status.
* @param {String} params.size_max Filters the response by a maximum image size, in bytes.
* @param {String} params.size_min Filters the response by a minimum image size, in bytes.
* @param {String} params.created_at Specify a comparison filter based on the date and time when the resource was created.
* @param {String} params.updated_at Specify a comparison filter based on the date and time when the resource was most recently modified.
* @param {String} params.sort_dir Sorts the response by a set of one or more sort direction and attribute (sort_key) combinations.
* @param {String} params.sort_key Sorts the response by an attribute, such as name, id, or updated_at.
* @param {String} params.sort Sorts the response by one or more attribute and sort direction combinations. You can also set multiple sort keys and directions. Default direction is desc.
* @returns {Promise}
*/
export const fetchImages = (params) =>
axios.request({
method: 'get',
url: cinderBase('images'),
params,
});
/**
* List image members
* @param {String} imageId The UUID of the image.
* @returns {Promise}
*/
export const fetchListImageMembers = (imageId) =>
axios.request({
method: 'get',
url: cinderBase(`images/${imageId}/members`),
});
/**
* Create image member
* @param {String} imageId The UUID of the image.
* @param {Object} data request body
* @param {String} data.member The ID of the image member.
* @returns {Promise}
*/
export const createImageMember = (imageId, data) =>
axios.request({
method: 'get',
url: cinderBase(`images/${imageId}/members`),
data,
});
/**
* Update image member
* @param {String} imageId The UUID of the image.
* @param {String} memberId The ID of the image member.
* @param {Object} data request body
* @param {String} data.status The status of this image member. Value is one of pending, accepted, rejected.
* @returns {Promise}
*/
export const updateImageMember = (imageId, memberId, data) =>
axios.request({
method: 'put',
url: cinderBase(`images/${imageId}/members/${memberId}`),
data,
});
/**
* Delete image member
* @param {String} imageId The UUID of the image.
* @param {String} memberId The ID of the image member.
* @returns {Promise}
*/
export const deleteImageMember = (imageId, memberId) =>
axios.request({
method: 'delete',
url: cinderBase(`images/${imageId}/members/${memberId}`),
});
/**
* List images count
* @param {Object} params request query
* @returns {Promise}
*/
export const fetchImagesCountOnGlance = (params) =>
axios.request({
method: 'get',
url: cinderBase('images/count'),
params,
});

106
src/api/glance/metadefs.js Normal file
View File

@ -0,0 +1,106 @@
// 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 axios from '@/libs/axios';
import cinderBase from './base';
/**
* Get namespace details
* @param {String} namespaceName The name of the namespace whose details you want to see.
* @param {Object} params request query
* @param {String} params.resource_type Apply the prefix for the specified resource type to the names of the properties listed in the response.
* @returns {Promise}
*/
export const fetchNamespaceDetailsOnGlance = (namespaceName, params) =>
axios.request({
method: 'get',
url: cinderBase(`metadefs/namespaces/${namespaceName}`),
params,
});
/**
* Update namespace
* @param {String} namespaceName The name of the namespace whose details you want to see.
* @param {Object} data request body
* @param {String} data.description The description of the namespace.
* @param {String} data.display_name User-friendly name to use in a UI to display the namespace name.
* @param {String} data.namespace An identifier (a name) for the namespace.
* @param {Boolean} data.protected Namespace protection for deletion. A valid value is true or false. Default is false.
* @param {String} data.visibility The namespace visibility. A valid value is public or private. Default is private.
* @returns {Promise}
*/
export const updateNamespaceOnGlance = (namespaceName, data) =>
axios.request({
method: 'put',
url: cinderBase(`metadefs/namespaces/${namespaceName}`),
data,
});
/**
* Create namespace
* @param {Object} data request body
* @param {String} data.description The description of the namespace.
* @param {String} data.display_name User-friendly name to use in a UI to display the namespace name.
* @param {String} data.namespace An identifier (a name) for the namespace.
* @param {Boolean} data.protected Namespace protection for deletion. A valid value is true or false. Default is false.
* @param {String} data.visibility The namespace visibility. A valid value is public or private. Default is private.
* @returns {Promise}
*/
export const createNamespaceOnGlance = (data) =>
axios.request({
method: 'post',
url: cinderBase('metadefs/namespaces'),
data,
});
/**
* List resource types
* @returns {Promise}
*/
export const fetchListResourceTypesOnGlance = () =>
axios.request({
method: 'get',
url: cinderBase('metadefs/resource_types'),
});
/**
* Remove resource type association
* @param {String} namespaceName The name of the namespace whose details you want to see.
* @param {String} resourceTypeName The name of the resource type.
* @returns {Promise}
*/
export const deleteResourceTypeOnGlance = (namespaceName, resourceTypeName) =>
axios.request({
method: 'delete',
url: cinderBase(
`metadefs/namespaces/${namespaceName}/resource_types/${resourceTypeName}`
),
});
/**
* Create resource type association
* @param {String} namespaceName The name of the namespace whose details you want to see.
* @param {Object} data request body
* @param {String} data.name Name of the resource type. A Name is limited to 80 chars in length.
* @param {String} data.prefix Prefix for any properties in the namespace that you want to apply to the resource type.
* @param {String} data.properties_target Some resource types allow more than one key and value pair for each instance.
* @returns {Promise}
*/
export const createResourceTypeOnGlance = (namespaceName, data) =>
axios.request({
method: 'post',
url: cinderBase(`metadefs/namespaces/${namespaceName}/resource_types`),
data,
});

23
src/api/gocron/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { gocronBase } from 'utils/constants';
const getGocronBaseUrl = (key) => `${gocronBase()}/${key}`;
export default getGocronBaseUrl;

23
src/api/heat/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { heatBase } from 'utils/constants';
const getHeatBaseUrl = (key) => `${heatBase()}/${key}`;
export default getHeatBaseUrl;

86
src/api/heat/stacks.js Normal file
View File

@ -0,0 +1,86 @@
// 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 axios from '@/libs/axios';
import getHeatBaseUrl from './base';
/**
* Create stack
* @param {Object} tenantId The UUID of the tenant. A tenant is also known as a project.
* @param {Object} data request body
* @see https://docs.openstack.org/api-ref/orchestration/v1/index.html?expanded=create-stack-detail#stacks
* @returns {Promise}
*/
export const createStackOnHeat = (tenantId, data) =>
axios.request({
method: 'post',
url: getHeatBaseUrl(`${tenantId}/stacks`),
data,
});
/**
* Update stack
* @param {Object} tenantId The UUID of the tenant. A tenant is also known as a project.
* @param {Object} stackName The name of a stack.
* @param {Object} stackId The UUID of the stack.
* @param {Object} data request body
* @see https://docs.openstack.org/api-ref/orchestration/v1/index.html?expanded=update-stack-detail#stacks
* @returns {Promise}
*/
export const updateStackOnHeat = (tenantId, stackName, stackId, data) =>
axios.request({
method: 'post',
url: getHeatBaseUrl(`${tenantId}/stacks/${stackName}/${stackId}`),
data,
});
/**
* Delete stack
* @param {Object} tenantId The UUID of the tenant. A tenant is also known as a project.
* @param {Object} stackName The name of a stack.
* @param {Object} stackId The UUID of the stack.
* @returns {Promise}
*/
export const deleteStackOnHeat = (tenantId, stackName, stackId) =>
axios.request({
method: 'delete',
url: getHeatBaseUrl(`${tenantId}/stacks/${stackName}/${stackId}`),
});
/**
* Abandon stack
* @param {Object} tenantId The UUID of the tenant. A tenant is also known as a project.
* @param {Object} stackName The name of a stack.
* @param {Object} stackId The UUID of the stack.
* @returns {Promise}
*/
export const abandonStackOnHeat = (tenantId, stackName, stackId) =>
axios.request({
method: 'delete',
url: getHeatBaseUrl(`${tenantId}/stacks/${stackName}/${stackId}/abandon`),
});
/**
* Get stack template
* @param {Object} tenantId The UUID of the tenant. A tenant is also known as a project.
* @param {Object} stackName The name of a stack.
* @param {Object} stackId The UUID of the stack.
* @returns {Promise}
*/
export const fetchStackTemplateOnHeat = (tenantId, stackName, stackId) =>
axios.request({
method: 'get',
url: getHeatBaseUrl(`${tenantId}/stacks/${stackName}/${stackId}/template`),
});

View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { ironicInspectorBase } from 'utils/constants';
const getIronicInspectorBaseUrl = (key) => `${ironicInspectorBase()}/${key}`;
export default getIronicInspectorBaseUrl;

23
src/api/ironic/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { ironicBase } from 'utils/constants';
const getIronicBaseUrl = (key) => `${ironicBase()}/${key}`;
export default getIronicBaseUrl;

205
src/api/ironic/nodes.js Normal file
View File

@ -0,0 +1,205 @@
// 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 axios from '@/libs/axios';
import getIronicBaseUrl from './base';
/**
* Create Node
* @param {Object} data request body
* @param {String} data.console_interface The boot interface for a Node, e.g. pxe.
* @param {String} data.conductor_group The conductor group for a node.
* @param {String} data.console_interface The console interface for a node, e.g. no-console.
* @param {String} data.deploy_interface The deploy interface for a node, e.g. iscsi.
* @param {String} data.driver_info All the metadata required by the driver to manage this Node.
* @param {String} data.driver The name of the driver used to manage this Node.
* @param {String} data.extra A set of one or more arbitrary metadata key and value pairs.
* @param {String} data.inspect_interface The interface used for node inspection, e.g. no-inspect.
* @param {String} data.management_interface Interface for out-of-band node management, e.g. ipmitool.
* @param {String} data.name Human-readable identifier for the Node resource. May be undefined. Certain words are reserved.
* @param {String} data.network_interface Which Network Interface provider to use when plumbing the network connections for this Node.
* @param {String} data.power_interface Interface used for performing power actions on the node, e.g. ipmitool.
* @param {String} data.properties Physical characteristics of this Node.
* @param {String} data.raid_interface Interface used for configuring RAID on this node, e.g. no-raid.
* @param {String} data.rescue_interface The interface used for node rescue, e.g. no-rescue.
* @param {String} data.resource_class A string which can be used by external schedulers to identify this Node as a unit of a specific type of resource.
* @param {String} data.storage_interface Interface used for attaching and detaching volumes on this node, e.g. cinder.
* @see https://docs.openstack.org/api-ref/baremetal/?expanded=create-node-detail
* @returns {Promise}
*/
export const createNodeOnIronic = (data) =>
axios.request({
method: 'post',
url: getIronicBaseUrl('nodes'),
data,
});
/**
* Update Node
* @param {String} nodeIdent The UUID or Name of the node.
* @see https://docs.openstack.org/api-ref/baremetal/?expanded=update-node-detail
* @returns {Promise}
*/
export const updateNodeOnIronic = (nodeIdent, data) =>
axios.request({
method: 'patch',
url: getIronicBaseUrl(`nodes/${nodeIdent}`),
data,
});
/**
* Node State Summary
* @param {String} nodeIdent The UUID or Name of the node.
* @returns {Promise}
*/
export const fetchNodeStateSummaryOnIronic = (nodeIdent) =>
axios.request({
method: 'get',
url: getIronicBaseUrl(`nodes/${nodeIdent}/states`),
});
/**
* Validate Node
* @param {String} nodeIdent The UUID or Name of the node.
* @returns {Promise}
*/
export const fetchNodeValidateOnIronic = (nodeIdent) =>
axios.request({
method: 'get',
url: getIronicBaseUrl(`nodes/${nodeIdent}/validate`),
});
/**
* List Ports by Node
* @param {String} nodeIdent The UUID or Name of the node.
* @returns {Promise}
*/
export const fetchNodePortsOnIronic = (nodeIdent) =>
axios.request({
method: 'get',
url: getIronicBaseUrl(`nodes/${nodeIdent}/ports`),
});
/**
* Change Node Provision State
* @param {String} nodeIdent The UUID or Name of the node.
* @param {Object} data request body
* @param {String} data.target The requested provisioning state of this Node.
* @param {String | Object} data.configdrive A config drive to be written to a partition on the Nodes boot disk.
* @param {Array} data.clean_steps An ordered list of cleaning steps that will be performed on the node.
* @param {Array} data.deploy_steps A list of deploy steps that will be performed on the node.
* @param {String} data.rescue_password Non-empty password used to configure rescue ramdisk during node rescue operation.
* @param {Boolean} data.disable_ramdisk If set to true, the ironic-python-agent ramdisk will not be booted for cleaning.
* @returns {Promise}
*/
export const changeNodeProvisionStateOnIronic = (nodeIdent, data) =>
axios.request({
method: 'put',
url: getIronicBaseUrl(`nodes/${nodeIdent}/states/provision`),
data,
});
/**
* Change Node Power State
* @param {String} nodeIdent The UUID or Name of the node.
* @param {Object} data request body
* @param {String} data.target Avaliable value : power on, power off, rebooting, soft power off or soft rebooting.
* @param {Number} data.timeout Timeout (in seconds) for a power state transition.
* @returns {Promise}
*/
export const changeNodePowerStateOnIronic = (nodeIdent, data) =>
axios.request({
method: 'put',
url: getIronicBaseUrl(`nodes/${nodeIdent}/states/power`),
data,
});
/**
* Set Maintenance Flag
* @param {String} nodeIdent The UUID or Name of the node.
* @param {Object} data request body
* @param {String} data.reason Specify the reason for setting the Node into maintenance mode.
* @returns {Promise}
*/
export const setMaintenanceFlagOnIronic = (nodeIdent, data) =>
axios.request({
method: 'put',
url: getIronicBaseUrl(`nodes/${nodeIdent}/maintenance`),
data,
});
/**
* Clear Maintenance Flag
* @param {String} nodeIdent The UUID or Name of the node.
* @returns {Promise}
*/
export const deleteMaintenanceFlagOnIronic = (nodeIdent) =>
axios.request({
method: 'delete',
url: getIronicBaseUrl(`nodes/${nodeIdent}/maintenance`),
});
/**
* Get Boot Device
* @param {String} nodeIdent The UUID or Name of the node.
* @returns {Promise}
*/
export const fetchBootDeviceOnIronic = (nodeIdent) =>
axios.request({
method: 'get',
url: getIronicBaseUrl(`nodes/${nodeIdent}/management/boot_device`),
});
/**
* Set Boot Device
* @param {String} nodeIdent The UUID or Name of the node.
* @param {Object} data request body
* @param {String} data.boot_device The boot device for a Node, eg. pxe or disk.
* @param {String} data.persistent Whether the boot device should be set only for the next reboot, or persistently.
* @returns {Promise}
*/
export const setBootDeviceOnIronic = (nodeIdent, data) =>
axios.request({
method: 'put',
url: getIronicBaseUrl(`nodes/${nodeIdent}/management/boot_device`),
data,
});
/**
* Get Supported Boot Devices
* @param {String} nodeIdent The UUID or Name of the node.
* @returns {Promise}
*/
export const fetchBootDeviceSupportedOnIronic = (nodeIdent) =>
axios.request({
method: 'get',
url: getIronicBaseUrl(
`nodes/${nodeIdent}/management/boot_device/supported`
),
});
/**
* Set all traits of a node
* @param {String} nodeIdent The UUID or Name of the node.
* @param {Object} data request body
* @param {Object} data.traits List of traits for this node.
* @returns {Promise}
*/
export const setAllTraitsOnIronic = (nodeIdent, data) =>
axios.request({
method: 'put',
url: getIronicBaseUrl(`nodes/${nodeIdent}/traits`),
data,
});

View File

@ -0,0 +1,51 @@
// 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 axios from '@/libs/axios';
import getIronicBaseUrl from './base';
/**
* Create Portgroup
* @param {Object} data request body
* @param {String} data.node_uuid UUID of the Node this resource belongs to.
* @param {String} data.address Physical hardware address of this network Port.
* @param {String} data.name Human-readable identifier for the Portgroup resource. May be undefined.
* @param {Object} data.mode Mode of the port group.
* @param {Boolean} data.standalone_ports_supported Indicates whether ports that are members of this portgroup can be used as stand-alone ports.
* @param {String} data.properties Key/value properties related to the port groups configuration.
* @param {String} data.extra A set of one or more arbitrary metadata key and value pairs.
* @param {String} data.uuid The UUID for the resource.
* @see https://docs.openstack.org/api-ref/baremetal/?expanded=set-all-traits-of-a-node-detail,create-portgroup-detail
*/
export const createPortGroupOnIronic = (data) =>
axios.request({
method: 'post',
url: getIronicBaseUrl('portgroups'),
data,
});
/**
* Update a Port
* @param {String} portId The UUID of the port.
* @param {Object} data request body
* @see https://docs.openstack.org/api-ref/baremetal/?expanded=set-all-traits-of-a-node-detail,update-a-portgroup-detail
* @returns {Promise}
*/
export const updatePortGroupOnIronic = (portgroupIdent, data) =>
axios.request({
method: 'patch',
url: getIronicBaseUrl(`portgroups/${portgroupIdent}`),
data,
});

63
src/api/ironic/ports.js Normal file
View File

@ -0,0 +1,63 @@
// 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 axios from '@/libs/axios';
import getIronicBaseUrl from './base';
/**
* List Detailed Ports
* @param {Object} params request query
* @param {String} params.node Filter the list of returned Ports.
*/
export const fetchDetailedPortsOnIronic = (params) =>
axios.request({
method: 'get',
url: getIronicBaseUrl('ports'),
params,
});
/**
* Create Port
* @param {Object} data request body
* @param {String} data.node_uuid UUID of the Node this resource belongs to.
* @param {String} data.address Physical hardware address of this network Port.
* @param {String} data.portgroup_uuid UUID of the Portgroup this resource belongs to.
* @param {Object} data.local_link_connection The Port binding profile.
* @param {Boolean} data.pxe_enabled Indicates whether PXE is enabled or disabled on the Port.
* @param {String} data.physical_network The name of the physical network to which a port is connected. May be empty.
* @param {String} data.extra A set of one or more arbitrary metadata key and value pairs.
* @param {Boolean} data.is_smartnicIndicates whether the Port is a Smart NIC port.
* @param {String} data.uuid The UUID for the resource.
*/
export const createPortsOnIronic = (data) =>
axios.request({
method: 'post',
url: getIronicBaseUrl('ports'),
data,
});
/**
* Update a Port
* @param {String} portId The UUID of the port.
* @param {Object} data request body
* @see https://docs.openstack.org/api-ref/baremetal/?expanded=set-all-traits-of-a-node-detail,update-a-port-detail
* @returns {Promise}
*/
export const updatePortsOnIronic = (portId, data) =>
axios.request({
method: 'patch',
url: getIronicBaseUrl(`ports/${portId}`),
data,
});

23
src/api/keystone/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { keystoneBase } from 'utils/constants';
const getKeystoneBaseUrl = (key) => `${keystoneBase()}/${key}`;
export default getKeystoneBaseUrl;

134
src/api/keystone/domain.js Normal file
View File

@ -0,0 +1,134 @@
// 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 axios from '@/libs/axios';
import getKeystoneBaseUrl from './base';
/**
* List domains
* @returns {Promise}
*/
export const fetchDomains = () =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl('domains'),
});
/**
* Show domain details
* @param {String} domainId The domain ID.
* @returns {Promise}
*/
export const fetchDomainDetails = (domainId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`domains/${domainId}`),
});
/**
* Update domain
* @param {String} domainId The domain ID.
* @param {Object} data request body
* @param {Object} data request body
* @returns {Promise}
*/
export const updateDomain = (domainId, data) =>
axios.request({
method: 'patch',
url: getKeystoneBaseUrl(`domains/${domainId}`),
data,
});
/**
* List role assignments for user on domain
* @param {String} domainId The domain ID.
* @param {String} userId The user ID.
* @returns {Promise}
*/
export const fetchRolesOnDomain = (domainId, userId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`domains/${domainId}/users/${userId}/roles`),
});
/**
* Assign role to user on domain
* @param {String} domainId The domain ID.
* @param {String} userId The user ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const updateRoleOnDomain = (domainId, userId, roleId) =>
axios.request({
method: 'put',
url: getKeystoneBaseUrl(
`domains/${domainId}/users/${userId}/roles/${roleId}`
),
});
/**
* Unassigns role from user on domain
* @param {String} domainId The domain ID.
* @param {String} userId The user ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const deleteRoleOnDomain = (domainId, userId, roleId) =>
axios.request({
method: 'delete',
url: getKeystoneBaseUrl(
`domains/${domainId}/users/${userId}/roles/${roleId}`
),
});
/**
* List role assignments for group on domain
* @param {String} domainId The domain ID.
* @param {String} groupId The group ID.
* @returns {Promise}
*/
export const fetchRolesForGroupOnDomain = (domainId, groupId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`domains/${domainId}/groups/${groupId}/roles`),
});
/**
* Assign role to group on domain
* @param {String} domainId The domain ID.
* @param {String} groupId The group ID.
* @returns {Promise}
*/
export const assignRoleForGroupOnDomain = (domainId, groupId, roleId) =>
axios.request({
method: 'put',
url: getKeystoneBaseUrl(
`domains/${domainId}/groups/${groupId}/roles/${roleId}`
),
});
/**
* Assign role to group on domain
* @param {String} domainId The domain ID.
* @param {String} groupId The group ID.
* @returns {Promise}
*/
export const unassignRoleForGroupOnDomain = (domainId, groupId, roleId) =>
axios.request({
method: 'delete',
url: getKeystoneBaseUrl(
`domains/${domainId}/groups/${groupId}/roles/${roleId}`
),
});

113
src/api/keystone/group.js Normal file
View File

@ -0,0 +1,113 @@
// 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 axios from '@/libs/axios';
import getKeystoneBaseUrl from './base';
/**
* List groups
* @param {String} groupId path
* @param {Object} parmas request query
* @param {String} parmas.name Filters the response by a group name.
* @param {String} parmas.domain_id Filters the response by a domain ID.
* @returns {Promise}
*/
export const fetchGroups = (parmas) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl('groups'),
parmas,
});
/**
* Show group details
* @param {String} groupId path
* @returns {Promise}
*/
export const fetchGroupDetails = (groupId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`groups/${groupId}`),
});
/**
* List users in group
* @param {String} groupId path
* @param {Object} parmas request query
* @param {String} parmas.password_expires_at Filter results based on which user passwords have expired.
* @returns {Promise}
*/
export const fetchGroupUsers = (groupId, parmas) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`groups/${groupId}/users`),
parmas,
});
/**
* Remove user from group
* @param {String} groupId The group ID.
* @param {String} userId The user ID.
* @returns {Promise}
*/
export const deleteGroupUsers = (groupId, userId) =>
axios.request({
method: 'delete',
url: getKeystoneBaseUrl(`groups/${groupId}/users/${userId}`),
});
/**
* Add user to group
* @param {String} groupId The group ID.
* @param {String} userId The user ID.
* @returns {Promise}
*/
export const addGroupUsers = (groupId, userId) =>
axios.request({
method: 'put',
url: getKeystoneBaseUrl(`groups/${groupId}/users/${userId}`),
});
/**
* Create group
* @param {Object} data request body
* @param {Object} data.group request body
* @param {Object} data.group.description The description of the group.
* @param {Object} data.group.domain_id The ID of the domain of the group.
* @param {Object} data.group.name The name of the group.
* @returns {Promise}
*/
export const createGroup = (groupId, data) =>
axios.request({
method: 'post',
url: getKeystoneBaseUrl('groups'),
data,
});
/**
* Update group
* @param {Object} data request body
* @param {Object} data.group request body
* @param {Object} data.group.description The description of the group.
* @param {Object} data.group.domain_id The ID of the domain of the group.
* @param {Object} data.group.name The name of the group.
* @returns {Promise}
*/
export const updateGroup = (groupId, data) =>
axios.request({
method: 'patch',
url: getKeystoneBaseUrl(`groups/${groupId}`),
data,
});

170
src/api/keystone/project.js Normal file
View File

@ -0,0 +1,170 @@
// 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 axios from '@/libs/axios';
import getKeystoneBaseUrl from './base';
/**
* List projects
* @returns {Promise}
*/
export const fetchProjects = () =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl('projects'),
});
/**
* Show project details
* @param {String} projectId path
* @returns {Promise}
*/
export const fetchProject = (projectId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`projects/${projectId}`),
});
/**
* Create project
* @param {Object} data request body
* @param {Object} data.project A project object
* @param {String} data.project.name The name of the project, which must be unique within the owning domain
* @param {Boolean} data.project.domain_id The ID of the domain for the project.
* @param {String} data.project.description The description of the project.
* @param {Boolean} data.project.enabled If set to true, project is enabled. If set to false, project is disabled.
* @returns {Promise}
*/
export const createProject = (data) =>
axios.request({
method: 'post',
url: getKeystoneBaseUrl('projects}'),
data,
});
/**
* Update project
* @param {String} projectId The project ID.
* @param {Object} data request body
* @param {Object} data.project A project object
* @param {String} data.project.name The name of the project
* @param {String} data.project.description The description of the project.
* @param {Boolean} data.project.enabled If set to true, project is enabled. If set to false, project is disabled.
* @returns {Promise}
*/
export const updateProject = (projectId, data) =>
axios.request({
method: 'patch',
url: getKeystoneBaseUrl(`projects/${projectId}`),
data,
});
/**
* List role assignments for user on project
* @param {String} projectId projects id
* @param {String} userId users id
* @returns {Promise}
*/
export const fetchRolesOnProject = (projectId, userId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`projects/${projectId}/users/${userId}/roles`),
});
/**
* List role assignments for group on project
* @param {String} projectId projects id
* @param {String} groupId groups id
* @returns {Promise}
*/
export const fetchRolesForGroupOnProject = (projectId, groupId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`projects/${projectId}/groups/${groupId}/roles`),
});
/**
* Modify tag list for a project
* @param {String} projectId The project ID.
* @param {Object} data request body
* @param {Array[String]} data.tags example : ["foo", "bar"]
* @returns {Promise}
*/
export const updateTagsOnProject = (projectId, data) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`projects/${projectId}/tags`),
data,
});
/**
* Assign role to group on project
* @param {String} projectId The project ID.
* @param {String} groupId The group ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const assignRoleToGroupOnProject = (projectId, groupId, roleId) =>
axios.request({
method: 'put',
url: getKeystoneBaseUrl(
`projects/${projectId}/groups/${groupId}/roles/${roleId}`
),
});
/**
* Assign role to group on project
* @param {String} projectId The project ID.
* @param {String} groupId The group ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const unassignRoleToGroupOnProject = (projectId, groupId, roleId) =>
axios.request({
method: 'delete',
url: getKeystoneBaseUrl(
`projects/${projectId}/groups/${groupId}/roles/${roleId}`
),
});
/**
* Assign role to user on project
* @param {String} projectId The project ID.
* @param {String} userId The user ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const assignRoleToUserOnProject = (projectId, userId, roleId) =>
axios.request({
method: 'put',
url: getKeystoneBaseUrl(
`projects/${projectId}/users/${userId}/roles/${roleId}`
),
});
/**
* Unassign role from user on project
* @param {String} projectId The project ID.
* @param {String} userId The user ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const unassignRoleToUserOnProject = (projectId, userId, roleId) =>
axios.request({
method: 'delete',
url: getKeystoneBaseUrl(
`projects/${projectId}/users/${userId}/roles/${roleId}`
),
});

View File

@ -0,0 +1,27 @@
// 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 axios from '@/libs/axios';
import getKeystoneBaseUrl from './base';
/**
* List role assignments
* @returns {Promise}
*/
export const fetchRoleAssignments = () =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl('role_assignments'),
});

38
src/api/keystone/role.js Normal file
View File

@ -0,0 +1,38 @@
// 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 axios from '@/libs/axios';
import getKeystoneBaseUrl from './base';
/**
* List roles
* @returns {Promise}
*/
export const fetchRoles = () =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl('roles'),
});
/**
* List implied (inference) roles for role
* @param {String} priorRoleId Role ID for a prior role.
* @returns {Promise}
*/
export const fetchImpliesForRole = (priorRoleId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`roles/${priorRoleId}/implies`),
});

View File

@ -0,0 +1,76 @@
// 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 axios from '@/libs/axios';
import getKeystoneBaseUrl from './base';
/**
* Assign a system role to a user
* @param {String} userId The user ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const updateSystemRole = (userId, roleId) =>
axios.request({
method: 'put',
url: getKeystoneBaseUrl(`system/users/${userId}/roles/${roleId}`),
});
/**
* Delete a system role assignment from a user
* @param {String} userId The user ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const deleteSystemRole = (userId, roleId) =>
axios.request({
method: 'delete',
url: getKeystoneBaseUrl(`system/users/${userId}/roles/${roleId}`),
});
/**
* List system role assignments for a group
* @param {String} groupId The group ID.
* @returns {Promise}
*/
export const fetchSystemRolesForGroup = (groupId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`system/groups/${groupId}/roles`),
});
/**
* Assign a system role to a group
* @param {String} groupId The group ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const assignSystemRoleForGroup = (groupId, roleId) =>
axios.request({
method: 'put',
url: getKeystoneBaseUrl(`system/groups/${groupId}/roles/${roleId}`),
});
/**
* Assign a system role to a group
* @param {String} groupId The group ID.
* @param {String} roleId The role ID.
* @returns {Promise}
*/
export const unassignSystemRoleForGroup = (groupId, roleId) =>
axios.request({
method: 'delete',
url: getKeystoneBaseUrl(`system/groups/${groupId}/roles/${roleId}`),
});

126
src/api/keystone/user.js Normal file
View File

@ -0,0 +1,126 @@
// 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 axios from '@/libs/axios';
import getKeystoneBaseUrl from './base';
/**
* List users
* @param {Object} params request query
* @param {String} params.domain_id Filters the response by a domain ID.
* @param {String} params.enabled Filters the response by either enabled (true) or disabled (false) users.
* @param {String} params.idp_id Filters the response by an identity provider ID.
* @param {String} params.name Filters the response by a user name.
* @param {String} params.password_expires_at Filter results based on which user passwords have expired.
* @param {String} params.protocol_id Filters the response by a protocol ID.
* @param {String} params.unique_id Filters the response by a unique ID.
* @returns {Promise}
*/
export const fetchUsers = () =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl('users'),
});
/**
* Show user details
* @param {String} userId The user ID.
* @returns {Promise}
*/
export const fetchUserDetails = (userId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`users/${userId}`),
});
/**
* Create user
* @param {Object} data request body
* @param {Object} data.user A user object
* @param {String} data.user.id id
* @param {String} data.user.domain_id The ID of the domain of the user, Default value : "default"
* @param {String} data.user.name The name for the user.
* @param {String} data.user.email The email for the user.
* @param {String} data.user.password The password for the user.
* @param {String} data.user.phone The phone for the user.
* @param {String} data.user.full_name The true name for the user.
* @param {Boolean} data.user.enabled Default value : true
* @param {String} data.user.description The description for the user.
* @returns {Promise}
*/
export const createUser = (data) =>
axios.request({
method: 'post',
url: getKeystoneBaseUrl('users'),
data,
});
/**
* Update user
* @param {String} userId The user ID.
* @param {Object} data request body
* @param {Object} data.user A user object
* @param {String} data.user.name The name for the user.
* @param {String} data.user.email The email for the user.
* @param {String} data.user.phone The phone for the user.
* @param {String} data.user.full_name The true name for the user.
* @param {String} data.user.description The description for the user.
* @returns {Promise}
*/
export const updateUser = (userId, data) =>
axios.request({
method: 'patch',
url: getKeystoneBaseUrl(`users/${userId}`),
data,
});
/**
* Change password for user
* @param {String} userId The user ID.
* @param {Object} data request body
* @param {Object} data.user A user object
* @param {String} data.user.original_password The original password for the user.
* @param {String} data.user.password The new password for the user.
* @returns {Promise}
*/
export const changeUserPassword = (userId, data) =>
axios.request({
method: 'post',
url: getKeystoneBaseUrl(`users/${userId}/password`),
data,
});
/**
* List projects for user
* @param {String} userId The user ID.
* @param {Object} params request query
* @returns {Promise}
*/
export const fetchUserProjects = (userId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`users/${userId}/projects`),
});
/**
* List groups to which a user belongs
* @param {String} userId The user ID.
* @returns {Promise}
*/
export const fetchUserGroups = (userId) =>
axios.request({
method: 'get',
url: getKeystoneBaseUrl(`users/${userId}/groups`),
});

79
src/api/neutron/agent.js Normal file
View File

@ -0,0 +1,79 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* List agents
* @returns {Promise}
*/
export const fetchAgents = () =>
axios.request({
method: 'get',
url: getNeutronBaseUrl('agents'),
});
/**
* Schedule a network to a DHCP agent
* @param {String} agentId The ID of the agent.
* @param {Object} data request body
* @param {String} data.network_id The ID of the network.
* @returns {Promise}
*/
export const addNetworkToDhcpAgent = (agentId, data) =>
axios.request({
method: 'post',
url: getNeutronBaseUrl(`agents/${agentId}/dhcp-networks`),
data,
});
/**
* Remove network from a DHCP agent
* @param {String} agentId The ID of the agent.
* @param {String} networkId The ID of the network.
* @returns {Promise}
*/
export const deleteNetworkToDhcpAgent = (agentId, networkId) =>
axios.request({
method: 'delete',
url: getNeutronBaseUrl(`agents/${agentId}/dhcp-networks/${networkId}`),
});
/**
* Schedule router to an l3 agent
* @param {String} agentId The ID of the agent.
* @param {Object} data request body
* @param {String} data.router_id The ID of the router.
* @returns {Promise}
*/
export const addRoterToL3Agent = (agentId, data) =>
axios.request({
method: 'post',
url: getNeutronBaseUrl(`agents/${agentId}/l3-routers`),
data,
});
/**
* Remove l3 router from an l3 agent
* @param {String} agentId The ID of the agent.
* @param {String} routerId The ID of the router.
* @returns {Promise}
*/
export const deleteL3RouterFromL3Agent = (agentId, routerId) =>
axios.request({
method: 'delete',
url: getNeutronBaseUrl(`agents/${agentId}/l3-routers/${routerId}`),
});

View File

@ -0,0 +1,32 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* List all availability zones
* @param {Object} params request query
* @param {String} params.state Filter the list result by the state of the availability zone, which is either available or unavailable.
* @param {String} params.resource Filter the list result by the resource type of the availability zone.
* @param {String} params.name Filter the list result by the human-readable name of the resource.
* @returns {Promise}
*/
export const fetchListAvailabilityZonesOnNeutron = (params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl('availability_zones'),
params,
});

23
src/api/neutron/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { neutronBase } from 'utils/constants';
const getNeutronBaseUrl = (key) => `${neutronBase()}/${key}`;
export default getNeutronBaseUrl;

View File

@ -0,0 +1,27 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* List extensions
* @returns {Promise}
*/
export const fetchListExtensionsOnNeutron = () =>
axios.request({
method: 'get',
url: getNeutronBaseUrl('extensions'),
});

View File

@ -0,0 +1,89 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* Update floating IP
* @param {String} floatingipId The ID of the floating IP address.
* @param {Object} data request body
* @param {Object} data.floatingip A floatingip object.
* @param {String} data.floatingip.port_id The ID of a port associated with the floating IP.
* @param {String} data.floatingip.fixed_ip_address The fixed IP address that is associated with the floating IP.
* @param {String} data.floatingip.description A human-readable description for the resource. Default is an empty string.
* @returns {Promise}
*/
export const updateFloatingIp = (floatingipId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`floatingips/${floatingipId}`),
data,
});
/**
* List floating IPs
* @param {String} floatingipId The ID of the floating IP address.
* @param {Object} query request query
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=list-floating-ips-detail#floating-ips-floatingips
* @returns {Promise}
*/
export const fetchListFloatingIps = (floatingipId, params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`floatingips/${floatingipId}`),
params,
});
/**
* List floating IP port forwardings
* @param {String} floatingipId The ID of the floating IP address.
* @param {Object} query request query
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=list-floating-ips-detail,list-floating-ip-port-forwardings-detail#floating-ips-floatingips
* @returns {Promise}
*/
export const fetchListPortForwardings = (floatingipId, params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`floatingips/${floatingipId}`),
params,
});
/**
* Create port forwarding
* @param {String} floatingipId The ID of the floating IP address.
* @param {Object} data request body
* @param {Object} data.port_forwarding A floating IP port forwarding object.
* @returns {Promise}
*/
export const createPortForwarding = (floatingipId, data) =>
axios.request({
method: 'post',
url: getNeutronBaseUrl(`floatingips/${floatingipId}/port_forwardings`),
data,
});
/**
* Delete a floating IP port forwarding
* @param {String} floatingipId The ID of the floating IP address.
* @param {String} portForwardingId The ID of the floating IP port forwarding.
*/
export const deletePortForwarding = (floatingipId, portForwardingId) =>
axios.request({
method: 'delete',
url: getNeutronBaseUrl(
`floatingips/${floatingipId}/port_forwardings/${{ portForwardingId }}`
),
});

View File

@ -0,0 +1,72 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* List networks
* @param {Object} params request query
* @param {Boolean} params.admin_state_up Filter the list result by the administrative state of the resource, which is up (true) or down (false).
* @param {Number} params.mtu Filter the network list result by the maximum transmission unit (MTU) value to address fragmentation. Minimum value is 68 for IPv4, and 1280 for IPv6.
* @param {String} params.name Filter the list result by the human-readable name of the resource.
* @param {String} params.project_id Filter the list result by the ID of the project that owns the resource.
* @param {String} params['provider:network_type'] Filter the list result by the type of physical network that this network/segment is mapped to.
* @param {String} params['provider:physical_network'] Filter the list result by the physical network where this network/segment is implemented.
* @param {String} params['provider:segmentation_id'] Filter the list result by the ID of the isolated segment on the physical network.
* @param {String} params.revision_number Filter the list result by the revision number of the resource.
* @param {Boolean} params.shared Filter the network list result based on if the network is shared across all tenants.
* @param {String} params.status Filter the network list result by network status. Values are ACTIVE, DOWN, BUILD or ERROR.
* @returns {Promise}
*/
export const fetchNetworksOnNeutron = (params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl('networks'),
params,
});
/**
* List DHCP agents hosting a network
* @param {String} networkId The ID of the attached network.
* @returns {Promise}
*/
export const fetchListDhcpAgentsOnNeutron = (networkId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`networks/${networkId}/dhcp-agents`),
});
/**
* Show network details
* @param {String} networkId The ID of the attached network.
* @returns {Promise}
*/
export const fetchNetworkDetailsOnNeutron = (networkId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`networks/${networkId}`),
});
/**
* Show Network IP Availability
* @param {String} networkId The ID of the attached network.
* @returns {Promise}
*/
export const fetchNetworkIpAvailabilityDetailsOnNeutron = (networkId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`network-ip-availabilities/${networkId}`),
});

58
src/api/neutron/ports.js Normal file
View File

@ -0,0 +1,58 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* List ports
* @param {Object} params request query
* @param {String} params.device_id Filter the port list result by the ID of the device that uses this port.
* @param {String} params.device_owner Filter the port result list by the entity type that uses this port.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=list-ports-detail#ports
*/
export const fetchPortsOnNeutron = (params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl('ports'),
params,
});
/**
* Update port
* @param {String} portId The ID of the port.
* @param {Object} data request body
* @param {String} data.port A port object.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=update-port-detail#ports
*/
export const updatePortOnNeutron = (portId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`ports/${portId}`),
data,
});
/**
* Create port
* @param {Object} data request body
* @param {String} data.port A port object.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=create-port-detail#ports
*/
export const createPortOnNeutron = (data) =>
axios.request({
method: 'post',
url: getNeutronBaseUrl('ports'),
data,
});

View File

@ -0,0 +1,144 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* Update QoS policy
* @param {String} policyId The ID of the QoS policy.
* @param {Object} data request body
* @param {Object} data.policy A QoS policy object.
* @param {String} data.policy.description A human-readable description for the resource. Default is an empty string.
* @param {Boolean} data.policy.is_default If true, the QoS policy is the default policy.
* @param {Boolean} data.policy.shared Set to true to share this policy with other projects. Default is false.
* @param {String} data.policy.name Human-readable name of the resource.
* @returns {Promise}
*/
export const updateQosPolicy = (policyId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`qos/policies/${policyId}`),
data,
});
/**
* Create bandwidth limit rule
* @param {String} policyId The ID of the QoS policy.
* @param {Object} data request body
* @param {Object} data.bandwidth_limit_rule A bandwidth_limit_rule object.
* @param {Number} data.bandwidth_limit_rule.max_kbps The maximum KBPS (kilobits per second) value.
* @param {Number} data.bandwidth_limit_rule.max_burst_kbps The maximum burst size (in kilobits). Default is 0.
* @param {Boolean} data.bandwidth_limit_rule.direction Valid values are egress and ingress. Default value is egress.
* @returns {Promise}
*/
export const createBandwidthLimitRulesQosPolicy = (policyId, data) =>
axios.request({
method: 'post',
url: getNeutronBaseUrl(`qos/policies/${policyId}/bandwidth_limit_rules`),
data,
});
/**
* Update bandwidth limit rule
* @param {String} policyId The ID of the QoS policy.
* @param {Object} ruleId The ID of the QoS rule.
* @param {Object} data request body
* @param {Object} data.bandwidth_limit_rule A bandwidth_limit_rule object.
* @param {Number} data.bandwidth_limit_rule.max_kbps The maximum KBPS (kilobits per second) value.
* @param {Number} data.bandwidth_limit_rule.max_burst_kbps The maximum burst size (in kilobits). Default is 0.
* @param {Boolean} data.bandwidth_limit_rule.direction Valid values are egress and ingress. Default value is egress.
* @returns {Promise}
*/
export const updateBandwidthLimitRulesQosPolicy = (policyId, ruleId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(
`qos/policies/${policyId}/bandwidth_limit_rules/${ruleId}`
),
data,
});
/**
* Delete bandwidth limit rule
* @param {String} policyId The ID of the QoS policy.
* @param {Object} ruleId The ID of the QoS rule.
* @returns {Promise}
*/
export const deleteBandwidthLimitRulesQosPolicy = (policyId, ruleId) =>
axios.request({
method: 'delete',
url: getNeutronBaseUrl(
`qos/policies/${policyId}/bandwidth_limit_rules/${ruleId}`
),
});
/**
* Create DSCP marking rule
* @param {String} policyId The ID of the QoS policy.
* @param {Object} data request body
* @param {Object} data.dscp_marking_rule A dscp_marking_rule object.
* @param {Number} data.dscp_marking_rule.dscp_mark The DSCP mark value.
* @returns {Promise}
*/
export const createDscpMarkingRuleQosPolicy = (policyId, data) =>
axios.request({
method: 'post',
url: getNeutronBaseUrl(`qos/policies/${policyId}/dscp_marking_rules`),
data,
});
/**
* Update DSCP marking rule
* @param {String} policyId The ID of the QoS policy.
* @param {String} dscpRuleId The ID of the DSCP rule.
* @param {Object} data request body
* @param {Object} data.dscp_marking_rule A dscp_marking_rule object.
* @param {Number} data.dscp_marking_rule.dscp_mark The DSCP mark value.
* @returns {Promise}
*/
export const updateDscpMarkingRuleQosPolicy = (policyId, dscpRuleId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(
`qos/policies/${policyId}/dscp_marking_rules/${dscpRuleId}`
),
data,
});
/**
* Delete DSCP marking rule
* @param {String} policyId The ID of the QoS policy.
* @param {String} dscpRuleId The ID of the DSCP rule.
* @returns {Promise}
*/
export const deleteDscpMarkingRuleQosPolicy = (policyId, dscpRuleId) =>
axios.request({
method: 'delete',
url: getNeutronBaseUrl(
`qos/policies/${policyId}/dscp_marking_rules/${dscpRuleId}`
),
});
/**
* Show QoS policy details
* @param {String} policyId The ID of the QoS policy.
* @returns {Promise}
*/
export const fetchQosPolicieDetailsOnNeutron = (policyId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`qos/policies/${policyId}`),
});

49
src/api/neutron/quotas.js Normal file
View File

@ -0,0 +1,49 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* Show quota details for a tenant
* @param {String} projectId The ID of the project.
* @returns {Promise}
*/
export const fetchQuotaDetails = (projectId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`quotas/${projectId}/details`),
});
/**
* Update quota for a project
* @param {String} projectId The ID of the project.
* @param {Object} data request body
* @param {Object} data.quota A quota object.
* @param {String} data.quota.floatingip The number of floating IP addresses allowed for each project. A value of -1 means no limit.
* @param {String} data.quota.network The number of networks allowed for each project. A value of -1 means no limit.
* @param {String} data.quota.router The number of routers allowed for each project. A value of -1 means no limit.
* @param {String} data.quota.subnet The number of subnets allowed for each project. A value of -1 means no limit.
* @param {String} data.quota.security_group The number of security groups allowed for each project. A value of -1 means no limit.
* @param {String} data.quota.security_group_rule The number of security group rules allowed for each project. A value of -1 means no limit.
* @param {String} data.quota.firewall_group A firewall group can have a firewall policy for ingress traffic and/or a firewall policy for egress traffic.
* @returns {Promise}
*/
export const updateQuotaDetails = (projectId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`quotas/${projectId}`),
data,
});

102
src/api/neutron/routers.js Normal file
View File

@ -0,0 +1,102 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* List routers
* @param {Object} params request query
* @param {String} params.project_id Filter the list result by the ID of the project that owns the resource.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=list-dhcp-agents-hosting-a-network-detail,show-subnet-details-detail,list-routers-detail#id5
* @returns {Promise}
*/
export const fetchListRoutersOnNeutron = (params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl('routers'),
params,
});
/**
* Show router details
* @param {String} routerId The ID of the router.
* @returns {Promise}
*/
export const fetchRouterDetailsOnNeutron = (routerId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`routers/${routerId}`),
});
/**
* Add extra routes to router
* @param {String} routerId The ID of the router.
* @param {Object} data request body
* @param {Object} data.router The router object.
* @param {Array} data.router.routes The extra routes configuration for L3 router.
* @returns {Promise}
*/
export const addExtraRoutesToRouterOnNeutron = (routerId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`routers/${routerId}/add_extraroutes`),
data,
});
/**
* Remove extra routes from router
* @param {String} routerId The ID of the router.
* @param {Object} data request body
* @param {Object} data.router The router object.
* @param {Array} data.router.routes The extra routes configuration for L3 router.
* @returns {Promise}
*/
export const removeExtraRoutesFromRouterOnNeutron = (routerId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`routers/${routerId}/remove_extraroutes`),
data,
});
/**
* Add interface to router
* @param {String} routerId The ID of the router.
* @param {Object} data request body
* @param {Object} data.subnet_id The ID of the subnet. One of subnet_id or port_id must be specified.
* @param {Array} data.port_id The ID of the port. One of subnet_id or port_id must be specified.
* @returns {Promise}
*/
export const addInterfaceToRouterOnNeutron = (routerId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`routers/${routerId}/add_router_interface`),
data,
});
/**
* Remove interface from router
* @param {String} routerId The ID of the router.
* @param {Object} data request body
* @param {Object} data.subnet_id The ID of the subnet. One of subnet_id or port_id must be specified.
* @param {Array} data.port_id The ID of the port. One of subnet_id or port_id must be specified.
* @returns {Promise}
*/
export const removeInterfaceFromRouterOnNeutron = (routerId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`routers/${routerId}/remove_router_interface`),
data,
});

View File

@ -0,0 +1,28 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* Show security group
* @param {securityGroupId} params The security group id
* @returns {Promise}
*/
export const fetchSecurityGroupsDetails = (securityGroupId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`security-groups/${securityGroupId}`),
});

View File

@ -0,0 +1,69 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* List subnets
* @param {Object} params request query
* @returns {Promise}
*/
export const fetchListSubnetsOnNeutron = (params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl('subnets'),
params,
});
/**
* Show subnet details
* @param {String} subnetId The ID of the subnet.
* @returns {Promise}
*/
export const fetchSubnetDetailsOnNeutron = (subnetId) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`subnets/${subnetId}`),
});
/**
* Create subnet
* @param {Object} data request body
* @param {Object} data.subnet A subnet object.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=list-dhcp-agents-hosting-a-network-detail,show-subnet-details-detail,list-routers-detail,create-subnet-detail#id5
* @returns {Promise}
*/
export const createSubnetOnNeutron = (data) =>
axios.request({
method: 'post',
url: getNeutronBaseUrl('subnets'),
data,
});
/**
* Update subnet
* @param {String} subnetId The ID of the subnet.
* @param {Object} data request body
* @param {Object} data.subnet A subnet object.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=list-ports-detail,update-subnet-detail#ports
* @returns {Promise}
*/
export const updateSubnetOnNeutron = (subnetId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`subnets/${subnetId}`),
data,
});

108
src/api/neutron/vpn.js Normal file
View File

@ -0,0 +1,108 @@
// 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 axios from '@/libs/axios';
import getNeutronBaseUrl from './base';
/**
* Update IKE policy
* @param {String} ikepolicyId The ID of the IKE policy.
* @param {Object} data request body
* @param {Object} data.ikepolicy An ikepolicy object.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=update-ike-policy-detail#vpnaas-2-0-vpn-vpnservices-ikepolicies-ipsecpolicies-endpoint-groups-ipsec-site-connections
* @returns {Promise}
*/
export const updateIkePolicyOnNeutron = (ikepolicyId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`vpn/ikepolicies/${ikepolicyId}`),
data,
});
/**
* Update IPsec connection
* @param {String} connectionId The ID of the IPsec site-to-site connection.
* @param {Object} data request body
* @param {Object} data.ipsec_site_connection An ipsec_site_connection object.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=update-ipsec-connection-detail#vpnaas-2-0-vpn-vpnservices-ikepolicies-ipsecpolicies-endpoint-groups-ipsec-site-connections
* @returns {Promise}
*/
export const updateIpConnectionOnNeutron = (connectionId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`vpn/ipsec-site-connections/${connectionId}`),
data,
});
/**
* Show IPsec connection
* @param {String} connectionId The ID of the IPsec site-to-site connection.
* @param {Object} params request query
* @returns {Promise}
*/
export const fetchIpConnectionDetailsOnNeutron = (connectionId, params) =>
axios.request({
method: 'get',
url: getNeutronBaseUrl(`vpn/ipsec-site-connections/${connectionId}`),
params,
});
/**
* Update VPN endpoint group
* @param {String} endpointGroupId The ID of the VPN endpoint group.
* @param {Object} data request body
* @param {Object} data.endpoint_group An ipsec_site_connection object.
* @param {Object} data.endpoint_group.name Human-readable name of the resource. Default is an empty string.
* @param {Object} data.endpoint_group.description A human-readable description for the resource. Default is an empty string.
* @returns {Promise}
*/
export const updateEndpointGroupOnNeutron = (endpointGroupId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`vpn/endpoint-groups/${endpointGroupId}`),
data,
});
/**
* Update VPN service
* @param {String} serviceId The ID of the VPN service.
* @param {Object} data request body
* @param {Object} data.vpnservice A vpnservice object.
* @param {Object} data.vpnservice.name Human-readable name of the resource. Default is an empty string.
* @param {Object} data.vpnservice.description A human-readable description for the resource. Default is an empty string.
* @param {Boolean} data.vpnservice.admin_state_up The administrative state of the resource, which is up (true) or down (false).
* @returns {Promise}
*/
export const updateVpnServiceNeutron = (serviceId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`vpn/vpnservices/${serviceId}`),
data,
});
/**
* Update IPsec policy
* @param {String} ipsecpolicyId The ID of the IPsec policy.
* @param {Object} data request body
* @param {Object} data.ipsecpolicy An ipsecpolicy object.
* @see https://docs.openstack.org/api-ref/network/v2/index.html?expanded=update-ipsec-policy-detail#vpnaas-2-0-vpn-vpnservices-ikepolicies-ipsecpolicies-endpoint-groups-ipsec-site-connections
* @returns {Promise}
*/
export const updateIpsecPolicyOnNeutron = (ipsecpolicyId, data) =>
axios.request({
method: 'put',
url: getNeutronBaseUrl(`vpn/ipsecpolicies/${ipsecpolicyId}`),
data,
});

23
src/api/nova/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { novaBase } from 'utils/constants';
const getNovaBaseUrl = (key) => `${novaBase()}/${key}`;
export default getNovaBaseUrl;

116
src/api/nova/flavor.js Normal file
View File

@ -0,0 +1,116 @@
// 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 axios from '@/libs/axios';
import getNovaBaseUrl from './base';
/**
* List Flavor Access Information For Given Flavor
* @param {String} flavorId The ID of the flavor.
* @returns {Promise}
*/
export const fetchFlavorAccessinfomation = (flavorId) =>
axios.request({
method: 'get',
url: getNovaBaseUrl(`flavors/${flavorId}/os-flavor-access`),
});
/**
* Create Flavor
* @param {Object} data request body
* @param {Object} data.flavor A flavor is a combination of memory, disk size, and CPUs.
* @param {String} data.flavor.name The display name of a flavor.
* @param {String} data.flavor.description A free form description of the flavor.
* @param {String} data.flavor.id The ID of the flavor.
* @param {Number} data.flavor.ram The amount of RAM a flavor has, in MiB.
* @param {Number} data.flavor.disk The size of the root disk that will be created in GiB.
* @param {Number} data.flavor.vcpus The number of virtual CPUs that will be allocated to the server.
* @param {Number} data.flavor.swap The size of a dedicated swap disk that will be allocated, in MiB.
* @param {Number} data.flavor['OS-FLV-EXT-DATA:ephemeral'] The size of the ephemeral disk that will be created, in GiB.
* @param {Number} data.flavor.rxtx_factor The receive / transmit factor (as a float) that will be set on ports if the network backend supports the QOS extension.
* @param {Boolean} data.flavor.['os-flavor-access:is_public'] Whether the flavor is public
* @returns {Promise}
*/
export const createFlavor = (data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl('flavors'),
data,
});
/**
* Add Or Remove Flavor Access To Tenant
* @param {String} flavorId The ID of the flavor.
* @param {Object} data request body
* @param {Object} data.addTenantAccess The action.
* @param {String} data.addTenantAccess.tenant The UUID of the tenant in a multi-tenancy cloud.
* @param {String} data.removeTenantAccess The action.
* @param {String} data.removeTenantAccess.tenant The UUID of the tenant in a multi-tenancy cloud.
* @returns {Promise}
*/
export const addOrDeleteFlavorAccessToTenant = (flavorId, data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl(`flavors/${flavorId}/action`),
data,
});
/**
* Create Extra Specs For A Flavor
* @param {String} flavorId The ID of the flavor.
* @param {Object} data request body
* @param {Object} data.extra_specs A dictionary of the flavors extra-specs key-and-value pairs.
* @param {String} data.extra_specs.key The extra spec key of a flavor.
* @param {String} data.extra_specs.value The extra spec value of a flavor.
* @returns {Promise}
*/
export const createExtraSpecsForFlavor = (flavorId, data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl(`flavors/${flavorId}/os-extra_specs`),
data,
});
/**
* Update An Extra Spec For A Flavor
* @param {String} flavorId The ID of the flavor.
* @param {Object} flavorExtraSpecKey The extra spec key for the flavor.
* @param {Object} data request body
* @param {String} data.key The extra spec key of a flavor.
* @param {String} data.value The extra spec value of a flavor.
* @returns {Promise}
*/
export const updateExtraSpecsForFlavor = (flavorId, flavorExtraSpecKey, data) =>
axios.request({
method: 'put',
url: getNovaBaseUrl(
`flavors/${flavorId}/os-extra_specs/${flavorExtraSpecKey}`
),
data,
});
/**
* Delete An Extra Spec For A Flavor
* @param {String} flavorId The ID of the flavor.
* @param {Object} flavorExtraSpecKey The extra spec key for the flavor.
* @returns {Promise}
*/
export const deleteExtraSpecsForFlavor = (flavorId, flavorExtraSpecKey) =>
axios.request({
method: 'delete',
url: getNovaBaseUrl(
`flavors/${flavorId}/os-extra_specs/${flavorExtraSpecKey}`
),
});

View File

@ -0,0 +1,32 @@
// 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 axios from '@/libs/axios';
import getNovaBaseUrl from './base';
/**
* Add Host, Remove Host, Create Or Update Aggregate Metadata
* @param {Object} data request body
* @param {Object} data.add_host when add host
* @param {Object} data.remove_host when remove host
* @param {Object} data.set_metadata when set metadata
* @returns {Promise}
*/
export const toggleChangeAggregate = (aggregateId, data) =>
axios.request({
method: 'get',
url: getNovaBaseUrl(`os-aggregates/${aggregateId}/action`),
data,
});

View File

@ -0,0 +1,38 @@
// 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 axios from '@/libs/axios';
import getNovaBaseUrl from './base';
/**
* List Hypervisors Details
* @returns {Promise}
*/
export const fetchOsHypervisorsDetails = () =>
axios.request({
method: 'get',
url: getNovaBaseUrl('os-hypervisors/detail'),
});
/**
* Show Hypervisor Details
* @param {String} hypervisorId path
* @returns {Promise}
*/
export const fetchOsHypervisorDetails = (hypervisorId) =>
axios.request({
method: 'get',
url: getNovaBaseUrl(`os-hypervisors/${hypervisorId}`),
});

View File

@ -0,0 +1,45 @@
// 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 axios from '@/libs/axios';
import getNovaBaseUrl from './base';
/**
* Show The Detail of Quota
* @returns {Promise}
*/
export const fetchOsQuotaSetsDetails = (tenantId) =>
axios.request({
method: 'get',
url: getNovaBaseUrl(`os-quota-sets/${tenantId}/detail`),
});
/**
* Update Quotas
* @param {String} tenantId The UUID of the tenant in a multi-tenancy cloud.
* @param {Object} data request body
* @param {Object} data.quota_set A quota object.
* @param {String} data.quota_set.instances The number of allowed servers for each tenant.
* @param {String} data.quota_set.cores The number of allowed server cores for each tenant.
* @param {String} data.quota_set.ram The amount of allowed server RAM, in MiB, for each tenant.
* @param {String} data.quota_set.server_groups The number of allowed server groups for each tenant.
* @returns {Promise}
*/
export const updateQuotaSets = (tenantId, data) =>
axios.request({
method: 'put',
url: getNovaBaseUrl(`os-quota-sets/${tenantId}`),
data,
});

View File

@ -0,0 +1,47 @@
// 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 axios from '@/libs/axios';
import getNovaBaseUrl from './base';
/**
* List Compute Services
* @param {Object} params request query
* @param {String} params.binary Filter the service list result by binary name of the service. example : nova-compute
* @param {String} params.host Filter the service list result by the host name.
* @returns {Promise}
*/
export const fetchOsServices = (params) =>
axios.request({
method: 'get',
url: getNovaBaseUrl('os-services'),
params,
});
/**
* Update Compute Service
* @param {String} serviceId The id of the service as a uuid.
* @param {Object} data request body
* @param {String} data.status The status of the service. One of enabled or disabled.
* @param {String} data.disabled_reason The reason for disabling a service.
* @param {Boolean} data.forced_down forced_down is a manual override to tell nova that the service in question has been fenced manually by the operations team.
* @returns {Promise}
*/
export const updateComputeService = (serviceId, data) =>
axios.request({
method: 'put',
url: getNovaBaseUrl(`os-services/${serviceId}`),
data,
});

202
src/api/nova/server.js Normal file
View File

@ -0,0 +1,202 @@
// 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 axios from '@/libs/axios';
import getNovaBaseUrl from './base';
/**
* Create server
* @param {Object} data request body
* @param {Object} data.server A server object
* @param {String} data.server.availability_zone availability_zone
* @param {Array[Object]} data.server.block_device_mapping_v2 example : [{boot_index:0,delete_on_termination:true,destination_type:"volume",source_type:"image",uuid:"66e129c5-7386-4620-b02a-8e578405e735",volume_size:10,volume_type:"9bcdbe9a-2e06-430f-a6a6-ba77c507cf51"}]
* @param {String} data.server.flavorRef The flavor reference, as an ID (including a UUID) or full URL, for the flavor for your server instance.
* @param {String} data.server.imageRef imageRef
* @param {String} data.server.key_name key_name
* @param {String} data.server.adminPass admins password
* @param {Number} data.server.min_count when count > 1
* @param {Number} data.server.max_count when count > 1
* @param {String} data.server.return_reservation_id when count > 1
* @param {String} data.server.name The server name
* @param {String} data.server.hypervisor_hostname when physicalNodeType.value !== "smart"
* @param {String} data.server.user_data Configuration information or scripts to use upon launch. Must be Base64 encoded. Restricted to 65535 bytes.
* @param {Object} data.server["OS-SCH-HNT:scheduler_hints"] example : {group: "xxxxx"}
* @param {Array[Object]} data.server.networks example : [{uuid: "xxxx"}]
* @param {Array[Object]} data.server.security_groups example : [{name: "xxxx"}]
* @returns {Promise}
*/
export const createServer = (data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl('servers'),
data,
});
/**
* Delete server
* @param {String} id The UUID of the server.
* @returns {Promise}
*/
export const deleteServer = (id) =>
axios.request({
method: 'delete',
url: getNovaBaseUrl(`servers/${id}`),
});
/**
* List Servers
* @param {Object} params request query
* @param {String} params.reservation_id A reservation id as returned by a servers multiple create call.
* @returns {Promise}
*/
export const fetchListServersOnNova = (params) =>
axios.request({
method: 'get',
url: getNovaBaseUrl('servers'),
params,
});
/**
* Show Server Details
* @param {String} serverId The UUID of the server.
* @param {Object} params request query
* @returns {Promise}
*/
export const fetchServerDetails = (serverId, params) =>
axios.request({
method: 'get',
url: getNovaBaseUrl(`servers/${serverId}`),
params,
});
/**
* Create Console
* @param {String} serverId The UUID of the server.
* @param {Object} data request body
* @param {Object} data.remote_console The remote console object.
* @param {String} data.remote_console.protocol The protocol of remote console.
* @param {String} data.remote_console.type The type of remote console.
* @returns {Promise}
*/
export const createConsoleOnServer = (serverId, data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl(`servers/${serverId}/remote-consoles`),
data,
});
/**
* Servers - run an administrative action
* @param {String} serverId The UUID of the server.
* @param {Object} data request body
* @param {String} data.injectNetworkInfo Inject Network Information (injectNetworkInfo Action
* @param {String} data.migrate The action to cold migrate a server.
* @returns {Promise}
*/
export const serverActionOnNova = (serverId, data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl(`servers/${serverId}/action`),
data,
});
/**
* List Port Interfaces
* @param {String} serverId The UUID of the server.
* @returns {Promise}
*/
export const fetchListPortInterfaces = (serverId) =>
axios.request({
method: 'get',
url: getNovaBaseUrl(`servers/${serverId}/os-interface`),
});
/**
* Create Interface
* @param {String} serverId The UUID of the server.
* @param {Object} data request body
* @param {Object} data.interfaceAttachment Specify the interfaceAttachment action in the request body.
* @param {Object} data.ip_address The IP address. It is required when fixed_ips is specified.
* @param {Object} data.port_id The ID of the port for which you want to create an interface.
* @param {Object} data.net_id The ID of the network for which you want to create a port interface.
* @param {Object} data.fixed_ips Fixed IP addresses.
* @param {Object} data.tag A device role tag that can be applied to a network interface when attaching it to the VM.
* @returns {Promise}
*/
export const createOsInterfaces = (serverId, data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl(`servers/${serverId}/os-interface`),
data,
});
/**
* Detach Interface
* @param {String} serverId The UUID of the server.
* @param {String} portId The UUID of the port.
* @returns {Promise}
*/
export const deletePortInterfaces = (serverId, portId) =>
axios.request({
method: 'delete',
url: getNovaBaseUrl(`servers/${serverId}/os-interface/${portId}`),
});
/**
* List volume attachments for an instance
* @param {String} serverId The UUID of the server.
* @param {Object} params request query
* @param {Number} params.limit max_limit
* @param {Number} params.offset offset is where to start in the list
* @returns {Promise}
*/
export const fetchVolumeAttachments = (serverId, params) =>
axios.request({
method: 'get',
url: getNovaBaseUrl(`servers/${serverId}/os-volume_attachments`),
params,
});
/**
* Attach a volume to an instance
* @param {String} serverId The UUID of the server.
* @param {Object} data The UUID of the port.
* @param {Object} data.volumeAttachment A dictionary representation of a volume attachment containing the fields device and volumeId.
* @param {Object} data.volumeAttachment.volumeId The UUID of the volume to attach.
* @param {Object} data.volumeAttachment.device Name of the device.
* @param {Object} data.volumeAttachment.tag A device role tag that can be applied to a volume when attaching it to the VM.
* @param {Boolean} data.volumeAttachment.delete_on_termination To delete the attached volume when the server is destroyed.
* @returns {Promise}
*/
export const attachVolumeOnInstance = (serverId, data) =>
axios.request({
method: 'post',
url: getNovaBaseUrl(`servers/${serverId}/os-volume_attachments}`),
data,
});
/**
* Detach a volume from an instance
* @param {String} serverId The UUID of the server.
* @param {Object} volumeId The UUID of the volume to detach.
* @returns {Promise}
*/
export const deleteVolumeOnInstance = (serverId, volumeId) =>
axios.request({
method: 'delete',
url: getNovaBaseUrl(
`servers/${serverId}/os-volume_attachments/${volumeId}}`
),
});

23
src/api/octavia/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { octaviaBase } from 'utils/constants';
const getOctaviaBaseUrl = (key) => `${octaviaBase()}/${key}`;
export default getOctaviaBaseUrl;

132
src/api/octavia/lbaas.js Normal file
View File

@ -0,0 +1,132 @@
// 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 axios from '@/libs/axios';
import getOctaviaBaseUrl from './base';
/**
* Update a Load Balancer
* @param {String} loadbalancerId The ID of the load balancer to query.
* @param {Object} data request body
* @param {Object} data.loadbalancer A load balancer object.
* @param {Boolean} data.loadbalancer.admin_state_up The administrative state of the resource, which is up (true) or down (false).
* @param {String} data.loadbalancer.name Human-readable name of the resource.
* @param {Array} data.loadbalancer.tags A list of simple strings assigned to the resource.
* @param {String} data.loadbalancer.vip_qos_policy_id The ID of the QoS Policy which will apply to the Virtual IP (VIP).
* @returns {Promise}
*/
export const updateLoadBalancer = (loadbalancerId, data) =>
axios.request({
method: 'put',
url: getOctaviaBaseUrl(`lbaas/loadbalancers/${loadbalancerId}`),
data,
});
/**
* List Load Balancers
* @param {Object} params request query
* @param {String} params.project_id The ID of the project to query.
* @param {String} params.fields A load balancer object.
* @returns {Promise}
*/
export const fetchListLoadBalancers = (params) =>
axios.request({
method: 'get',
url: getOctaviaBaseUrl('lbaas/loadbalancers'),
params,
});
/**
* Show Load Balancer details
* @param {String} loadbalancerId The ID of the load balancer to query.
* @param {Object} params request query
* @param {String} params.fields A load balancer object.
* @returns {Promise}
*/
export const fetchLoadBalancerDetails = (loadbalancerId, params) =>
axios.request({
method: 'get',
url: getOctaviaBaseUrl(`lbaas/loadbalancers/${loadbalancerId}`),
params,
});
/**
* Remove a Load Balancer
* @param {String} loadbalancerId The ID of the load balancer to query.
* @param {Object} params request query
* @param {Boolean} params.cascade If true will delete all child objects of the load balancer.
* @returns {Promise}
*/
export const deleteLoadBalancer = (loadbalancerId, params) =>
axios.request({
method: 'delete',
url: getOctaviaBaseUrl(`lbaas/loadbalancers/${loadbalancerId}`),
params,
});
/**
* Create Member
* @param {String} poolId The ID of the pool to query.
* @param {Object} data request body
* @param {Object} data.member The member object.
* @returns {Promise}
*/
export const createMemberOnOctavia = (poolId, data) =>
axios.request({
method: 'post',
url: getOctaviaBaseUrl(`lbaas/pools/${poolId}/members`),
data,
});
/**
* Batch Update Members
* @param {String} poolId The ID of the pool to query.
* @param {Object} data request body
* @param {Object} data.members The members object.
* @returns {Promise}
*/
export const batchUpdateMembersOnOctavia = (poolId, data) =>
axios.request({
method: 'put',
url: getOctaviaBaseUrl(`lbaas/pools/${poolId}/members`),
data,
});
/**
* Update A Member
* @param {String} poolId The ID of the pool to query.
* @param {String} memberId The ID of the member to query.
* @param {Object} data request body
* @param {Object} data.member The member object.
* @returns {Promise}
*/
export const updateAMemberOnOctavia = (poolId, memberId, data) =>
axios.request({
method: 'put',
url: getOctaviaBaseUrl(`lbaas/pools/${poolId}/members/${memberId}`),
data,
});
/**
* Delete A Member
* @param {String} poolId The ID of the pool to query.
* @param {String} memberId The ID of the member to query.
* @returns {Promise}
*/
export const deleteAMemberOnOctavia = (poolId, memberId) =>
axios.request({
method: 'delete',
url: getOctaviaBaseUrl(`lbaas/pools/${poolId}/members/${memberId}`),
});

28
src/api/octavia/pools.js Normal file
View File

@ -0,0 +1,28 @@
// 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 axios from '@/libs/axios';
import getOctaviaBaseUrl from './base';
/**
* Show Pool Details
* @param {Object} poolId The ID of the pool to query.
* @returns {Promise}
*/
export const fetchPoolDetailsOnOctavia = (poolId) =>
axios.request({
method: 'get',
url: getOctaviaBaseUrl(`pools/${poolId}`),
});

23
src/api/panko/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { pankoBase } from 'utils/constants';
const getPankoBaseUrl = (key) => `${pankoBase()}/${key}`;
export default getPankoBaseUrl;

50
src/api/panko/event.js Normal file
View File

@ -0,0 +1,50 @@
// 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 axios from '@/libs/axios';
import getPankoBaseUrl from './base';
/**
* List events
* @param {Object} params request query
* @param {String} params['q.field'] 'filter_self'
* @param {String} params['q.op'] 'le'
* @param {Boolean} params['q.value'] true or false
* @param {String} params.sort 'generated:desc'
* @param {Number} params.limit 10
* @param {String} params.mariker "string"
* @returns {Promise}
*/
export const fetchEvents = (params) =>
axios.request({
method: 'get',
url: getPankoBaseUrl('events'),
params,
});
/**
* Fetch count for event
* @param {Object} params request query
* @param {String} params['q.field'] 'filter_self'
* @param {String} params['q.op'] 'le'
* @param {Boolean} params['q.value'] true or false
* @returns {Promise}
*/
export const fetchEventCount = (params) =>
axios.request({
method: 'get',
url: getPankoBaseUrl('events/count'),
params,
});

23
src/api/placement/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { placementBase } from 'utils/constants';
const getPlacementBaseUrl = (key) => `${placementBase()}/${key}`;
export default getPlacementBaseUrl;

View File

@ -0,0 +1,28 @@
// 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 axios from '@/libs/axios';
import getPlacementBaseUrl from './base';
/**
* List resource provider inventories
* @param {String} uuid path
* @returns {Promise}
*/
export const fetchResourceProviderInventories = (uuid) =>
axios.request({
method: 'get',
url: getPlacementBaseUrl(`resource_providers/${uuid}/inventories`),
});

View File

@ -0,0 +1,31 @@
// 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 axios from '@/libs/axios';
import getPlacementBaseUrl from './base';
/**
* List traits
* @param {Object} params request query
* @param {String} params.name A string to filter traits.
* @param {Boolean} params.associated Available values for the parameter are true and false.
* @returns {Promise}
*/
export const fetchListTraitsOnPlacement = (params) =>
axios.request({
method: 'get',
url: getPlacementBaseUrl('traits'),
params,
});

23
src/api/skyline/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { skylineBase } from 'utils/constants';
const getSkylineBaseUrl = (key) => `${skylineBase()}/${key}`;
export default getSkylineBaseUrl;

View File

@ -0,0 +1,47 @@
// 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 axios from '@/libs/axios';
import getSkylineBaseUrl from './base';
/**
* List Keystone Endpoints
* @returns {Promise}
*/
export const fetchKeystoneEndpoints = () =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('contrib/keystone_endpoints'),
});
/**
* List Domains
* @returns {Promise}
*/
export const fetchDomains = () =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('contrib/domains'),
});
/**
* List Regions
* @returns {Promise}
*/
export const fetchRegions = () =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('contrib/regions'),
});

View File

@ -0,0 +1,155 @@
// 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 axios from '@/libs/axios';
import getSkylineBaseUrl from './base';
/**
* List Servers.
* Notes:
* The host of sort_keys is only used for admin/system_admin role users.
* The name is to support for fuzzy queries.
* @param {Object} params request query
* @param {Number} params.limit Default value : 10
* @param {String} params.marker marker
* @param {String} params.sort_dirs Available values : desc, asc
* @param {Array[String]} params.sort_keys Available values : uuid, display_name, vm_state, locked, created_at, host, project_id
* @param {Boolean} params.all_projects Default value : false
* @param {String} params.project_id Only works when the all_projects filter is also specified.
* @param {String} params.project_name Only works when the all_projects filter is also specified.
* @param {String} params.name name
* @param {String} params.floating_ip Floating IP of server.
* @param {String} params.fixed_ip Fixed IP of server.
* @param {String} params.status Available values : ACTIVE, BUILD, ERROR, HARD_REBOOT, MIGRATING, PAUSED, REBOOT, REBUILD, RESCUE, RESIZE, SHELVED, SHELVED_OFFLOADED, SHUTOFF, SOFT_DELETED, SUSPENDED, UNKNOWN
* @param {String} params.host It will be ignored for non-admin user.
* @param {String} params.flavor_id flavors id
* @param {Array[String]} params.uuid UUID of server.
* @returns {Promise}
*/
export const fetchListServers = (params) =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('extension/servers'),
params,
});
/**
* List Recycle Servers.
* Notes:
* The updated_at of sort_keys is used as deleted_at.
* The name is to support for fuzzy queries.
* @param {Object} params request query
* @param {Number} params.limit Default value : 10
* @param {String} params.marker marker
* @param {String} params.sort_dirs Available values : desc, asc
* @param {Array[String]} params.sort_keys Available values : uuid, display_name, updated_at, project_id
* @param {Boolean} params.all_projects Default value : false
* @param {String} params.project_id Only works when the all_projects filter is also specified.
* @param {String} params.project_name Only works when the all_projects filter is also specified.
* @param {String} params.name name
* @param {String} params.floating_ip Floating IP of server.
* @param {String} params.fixed_ip Fixed IP of server.
* @param {Array[String]} params.uuid UUID of server.
* @returns {Promise}
*/
export const fetchListRecycleServers = (params) =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('extension/recycle_servers'),
params,
});
/**
* List Volumes.
* @param {Object} params request query
* @param {Number} params.limit Default value : 10
* @param {String} params.marker marker
* @param {String} params.sort_dirs Available values : desc, asc
* @param {Array[String]} params.sort_keys Available values : id, name, size, status, bootable, created_at
* @param {Boolean} params.all_projects Default value : false
* @param {String} params.project_id Only works when the all_projects filter is also specified.
* @param {String} params.name name
* @param {Boolean} params.multiattach Default value : false
* @param {String} params.status Available values : creating, available, reserved, attaching, detaching, in-use, maintenance, deleting, awaiting-transfer, error, error_deleting, backing-up, restoring-backup, error_backing-up, error_restoring, error_extending, downloading, uploading, retyping, extending
* @param {Boolean} params.bootable Default value : false
* @param {Array[String]} params.uuid UUID of volume.
* @returns {Promise}
*/
export const fetchListVolumes = (params) =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('extension/volumes'),
params,
});
/**
* List Volume Snapshots.
* @param {Object} params request query
* @param {Number} params.limit Default value : 10
* @param {String} params.marker marker
* @param {String} params.sort_dirs Available values : desc, asc
* @param {Array[String]} params.sort_keys Available values : id, name, status, created_at
* @param {Boolean} params.all_projects Default value : false
* @param {String} params.project_id Only works when the all_projects filter is also specified.
* @param {String} params.name name
* @param {String} params.status Available values : CREATING, AVAILABLE, DELETING, ERROR, ERROR_DELETING
* @param {String} params.volume_id volumes id
* @returns {Promise}
*/
export const fetchListVolumeSnapshots = (params) =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('extension/volume_snapshots'),
params,
});
/**
* List Ports.
* @param {Object} params request query
* @param {Number} params.limit Default value : 10
* @param {String} params.marker marker
* @param {String} params.sort_dirs Available values : desc, asc
* @param {Array[String]} params.sort_keys Available values : id, name, mac_address, status, project_id
* @param {Boolean} params.all_projects Default value : false
* @param {String} params.project_id Only works when the all_projects filter is also specified.
* @param {String} params.name name
* @param {String} params.status Available values : ACTIVE, DOWN, BUILD, ERROR, N/A
* @param {String} params.network_name networks name
* @param {String} params.network_id networks id
* @param {String} params.device_id devices id
* @param {Array[String]} params.device_owner Available values : , compute:nova, network:dhcp, network:floatingip, network:router_gateway, network:router_ha_interface, network:ha_router_replicated_interface
* @param {Array[String]} params.uuid UUID of port.
* @returns {Promise}
*/
export const fetchListPorts = (params) =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('extension/ports'),
params,
});
/**
* List compute services.
* @param {Object} params request query
* @param {String} params.binary binary
* @param {String} params.host host
* @returns {Promise}
*/
export const fetchListComputeServices = (params) =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('extension/compute-services'),
params,
});

64
src/api/skyline/login.js Normal file
View File

@ -0,0 +1,64 @@
// 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 axios from '@/libs/axios';
import getSkylineBaseUrl from './base';
/**
* login
* @param {Object} data request body
* @param {String} data.region RegionOne
* @param {String} data.domain default
* @param {String} data.username admin
* @param {String} data.password password
* @returns {Promise}
*/
export const login = (data) =>
axios.request({
method: 'post',
url: getSkylineBaseUrl('login'),
data,
});
/**
* logout
* @returns {Promise}
*/
export const logout = () =>
axios.request({
method: 'post',
url: getSkylineBaseUrl('logout'),
});
/**
* fetch profile
* @returns {Promise}
*/
export const fetchProfile = () =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('profile'),
});
/**
* switch_project
* @param {String} projectId projects id
* @returns {Promise}
*/
export const switchProject = (projectId) =>
axios.request({
method: 'post',
url: getSkylineBaseUrl(`switch_project/${projectId}`),
});

40
src/api/skyline/policy.js Normal file
View File

@ -0,0 +1,40 @@
// 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 axios from '@/libs/axios';
import getSkylineBaseUrl from './base';
/**
* List policies
* @returns {Promise}
*/
export const fetchPolicies = () =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('policies'),
});
/**
* Check policies
* @param {Object} data request body
* @param {Array[String]} data.rules ["string"]
* @returns {Promise}
*/
export const checkPolicies = (data) =>
axios.request({
method: 'post',
url: getSkylineBaseUrl('policies/check'),
data,
});

View File

@ -0,0 +1,63 @@
// 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 axios from '@/libs/axios';
import getSkylineBaseUrl from './base';
/**
* Get a setting item.
* @param {String} key path
* @returns {Promise}
*/
export const fetchSetting = (key) =>
axios.request({
method: 'get',
url: getSkylineBaseUrl(`setting/${key}`),
});
/**
* Reset a setting item to default
* @param {String} key path
* @returns {Promise}
*/
export const resetSetting = (key) =>
axios.request({
method: 'delete',
url: getSkylineBaseUrl(`setting/${key}`),
});
/**
* Update a setting item.
* @param {Object} data request body
* @param {String} data.key "string"
* @param {String} data.value "string"
* @returns {Promise}
*/
export const updateSetting = (data) =>
axios.request({
method: 'put',
url: getSkylineBaseUrl('setting'),
data,
});
/**
* Get all settings.
* @returns {Promise}
*/
export const fetchAllSettings = () =>
axios.request({
method: 'get',
url: getSkylineBaseUrl('settings'),
});

View File

@ -0,0 +1,27 @@
// 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 axios from '@/libs/axios';
/**
* Create Storageclasses
* @param {Object} data request body
* @returns {Promise}
*/
export const createStorageclasses = (data) =>
axios.request({
method: 'post',
url: 'apis/storage.k8s.io/v1/storageclasses',
data,
});

23
src/api/swift/base.js Normal file
View File

@ -0,0 +1,23 @@
// 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.
/**
* @param {String} key api url
* @returns {String}
*/
import { swiftBase } from 'utils/constants';
const getSwiftBaseUrl = (key) => `${swiftBase()}/${key}`;
export default getSwiftBaseUrl;

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#333333" d="M504.149333 7.850667c-44.373333 108.544-70.997333 179.2-120.149333 284.330666 30.037333 32.085333 67.242667 69.290667 127.317333 111.274667-64.512-26.624-108.544-53.248-141.653333-80.896-63.146667 131.413333-161.792 318.464-361.813333 678.229333 157.696-90.794667 279.552-146.773333 393.216-168.277333-4.778667-21.162667-7.509333-43.690667-7.509334-67.584l0.341334-5.12c2.389333-100.693333 54.954667-178.517333 117.077333-173.056s110.592 91.477333 107.861333 192.170667c-0.341333 18.090667-2.389333 36.522667-6.485333 54.272 112.64 21.845333 233.130667 77.824 388.437333 167.594666l-83.968-155.648c-40.96-31.744-83.968-73.386667-171.349333-118.101333 60.074667 15.701333 103.082667 33.792 136.533333 53.930667-265.557333-493.909333-287.061333-559.786667-377.856-773.12z" /></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>SliceCopy</title>
<g id="登陆和概览" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理平台-HOME2【默认】" transform="translate(-609.000000, -1081.000000)" fill="#38B4FF" fill-rule="nonzero">
<g id="编组-27" transform="translate(609.000000, 1081.000000)">
<g id="SliceCopy">
<path d="M30,60 C13.4314575,60 0,46.5685425 0,30 C0,13.4314575 13.4314575,0 30,0 C46.5685425,0 60,13.4314575 60,30 C60,46.5685425 46.5685425,60 30,60 Z M30,56 C44.3594035,56 56,44.3594035 56,30 C56,15.6405965 44.3594035,4.00000002 30,4.00000002 C15.6405965,4.00000002 4.00000002,15.6405965 4.00000002,30 C4.00000002,44.3594035 15.6405965,56 30,56 Z M30,40 C24.4771525,40 20,35.5228475 20,30 C20,24.4771525 24.4771525,20 30,20 C35.5228475,20 40,24.4771525 40,30 C40,35.5228475 35.5228475,40 30,40 Z M30,36 C33.3137085,36 36,33.3137085 36,30 C36,26.6862915 33.3137085,24 30,24 C26.6862915,24 24,26.6862915 24,30 C24,33.3137085 26.6862915,36 30,36 L30,36 Z M26.14,9.95200002 C27.2412558,9.86363446 28.2056344,10.6847442 28.294,11.786 C28.3823655,12.8872558 27.5612558,13.8516344 26.46,13.94 C20.292,14.44 16.168,17.972 13.86,24.86 C13.4877031,25.876405 12.3743325,26.4121564 11.3477616,26.0688832 C10.3211908,25.72561 9.75402764,24.6279081 10.068,23.592 C12.864,15.244 18.296,10.588 26.14,9.95200002 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="62px" height="56px" viewBox="0 0 62 56" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>wangluo-2</title>
<g id="登陆和概览" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理平台-HOME2【默认】" transform="translate(-126.000000, -1007.000000)" fill="#38B4FF" fill-rule="nonzero">
<g id="编组-23" transform="translate(126.000000, 950.000000)">
<g id="wangluo-2" transform="translate(0.000000, 57.000000)">
<path d="M52.5344991,0.0391257436 C47.4440159,0.0391257436 43.3025408,3.89248428 43.3025408,8.62882963 C43.3025408,8.86987105 43.313773,9.10841772 43.3348605,9.34440232 L14.3815645,21.7517974 C12.9110949,20.8307832 11.1416326,20.2926035 9.23955843,20.2926035 C4.14900279,20.2926035 0.00760015534,24.1459621 0.00760015534,28.8823748 C0.00760015534,33.6187203 4.14907531,37.4720787 9.23955843,37.4720787 C11.4404802,37.4720787 13.4636442,36.7513818 15.0516529,35.5507597 L30.1020826,44.8291341 C29.838888,45.6259529 29.6968556,46.4716542 29.6968556,47.3476964 C29.6968556,52.0841092 33.8383308,55.9374003 38.9288139,55.9374003 C44.0193695,55.9374003 48.1607722,52.0841092 48.1607722,47.3476964 C48.1607722,42.611351 44.0193695,38.7579925 38.9288139,38.7579925 C36.1069353,38.7579925 33.5770927,39.9425677 31.8823423,41.8048905 L17.4077233,32.8815718 C18.086435,31.6863436 18.4715166,30.3255217 18.4715166,28.8824422 C18.4715166,27.2293366 17.9665771,25.6841769 17.093368,24.3725746 L44.3924218,12.6741447 C45.9494877,15.3765053 49.0149952,17.2186683 52.5344991,17.2186683 C57.6249823,17.2186683 61.7664574,13.3653773 61.7664574,8.62896444 C61.7664574,3.89248428 57.6249823,0.0391257436 52.5344991,0.0391257436 Z M38.9288863,42.1939279 C41.9832342,42.1939279 44.4680758,44.5059026 44.4680758,47.3476963 C44.4680758,50.1895575 41.9832341,52.5015321 38.9288863,52.5015321 C35.8746109,52.5015321 33.3897694,50.1895574 33.3897694,47.3476963 C33.3897694,44.5059026 35.8745385,42.1939279 38.9288863,42.1939279 Z M9.23948591,34.0362107 C6.18521049,34.0362107 3.70029649,31.724236 3.70029649,28.8824423 C3.70029649,26.0405811 6.18521056,23.7286065 9.23948591,23.7286065 C12.2937613,23.7286065 14.7786753,26.0406486 14.7786753,28.8824423 C14.7786753,31.724236 12.2938338,34.0362107 9.23948591,34.0362107 Z M52.5344991,13.7827329 C49.4801512,13.7827329 46.9953097,11.4706908 46.9953097,8.6288971 C46.9953097,5.7871034 49.4801513,3.47506131 52.5344991,3.47506131 C55.5888469,3.47506131 58.0736885,5.7871034 58.0736885,8.6288971 C58.0736885,11.4706908 55.5889195,13.7827329 52.5344991,13.7827329 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="67px" height="60px" viewBox="0 0 67 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>luyouqi</title>
<g id="登陆和概览" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理平台-HOME2【默认】" transform="translate(-890.000000, -1077.000000)" fill="#38B4FF" fill-rule="nonzero">
<g id="编组-41" transform="translate(890.000000, 1077.000000)">
<g id="luyouqi" transform="translate(-0.000000, 0.000000)">
<path d="M2.3561003,38.0507812 L10.197558,38.0507812 L10.197558,29.4607972 C10.197558,28.6955698 10.5640672,27.9824804 11.1284618,27.5653771 L11.1284618,18.4770303 C11.1284618,17.6964353 11.7602919,17.0982878 12.5240457,17.0982878 C13.3047109,17.0982878 13.9534525,17.6964353 13.9534525,18.4770303 L13.9534525,27.5653771 C14.5009356,27.9824804 14.865901,28.6955698 14.865901,29.460727 L14.865901,38.0508514 L45.9894274,38.0508514 L45.9894274,29.4607972 C45.9894274,28.6955698 46.3713043,27.9824804 46.9188576,27.5653771 L46.9188576,18.4770303 C46.9188576,17.6964353 47.5506877,17.0982878 48.3314231,17.0982878 C49.0950365,17.0982878 49.7437781,17.6964353 49.7437781,18.4770303 L49.7437781,27.5653771 C50.3081727,27.9824804 50.6577704,28.6955698 50.6577704,29.460727 L50.6577704,38.0508514 L58.5161396,38.0508514 C59.8135526,38.0508514 60.8765204,39.1305202 60.8765204,40.3927068 L60.8765204,57.4082616 C60.8765204,58.6873597 59.8135526,59.7685722 58.5161396,59.7685722 L2.35617047,59.7685722 C1.05868731,59.7685722 0.0127713323,58.6873597 0.0127713323,57.4083318 L0.0127713323,40.3926366 C0.0127713323,39.13045 1.05861714,38.0507812 2.3561003,38.0507812 Z M45.9390438,2.84162144 C50.791308,2.84162144 55.1944003,4.80159993 58.3689886,7.99155595 C61.5421033,11.1815821 63.5189231,15.5692365 63.5189231,20.403256 C63.5189231,21.1853948 64.1339119,21.7835423 64.9314184,21.7835423 C65.6951722,21.7835423 66.3100908,21.185465 66.3100908,20.403256 C66.3100908,14.8040092 64.0665466,9.67091598 60.3611761,5.99936845 C56.6727171,2.30943582 51.5719031,0.0489099925 45.9390438,0.0489099925 C45.1751497,0.0489099925 44.5601609,0.646987275 44.5601609,1.42919629 C44.5601609,2.19280969 45.1751497,2.84162144 45.9390438,2.84162144 L45.9390438,2.84162144 Z M45.9390438,11.1492328 C48.5155548,11.1492328 50.8249906,12.1783776 52.5029472,13.8408262 L52.6024513,13.9420846 C54.2312173,15.6030595 55.2111714,17.8957943 55.2111714,20.403256 C55.2111714,21.1853948 55.8415279,21.7835423 56.6235966,21.7835423 C57.3873503,21.7835423 58.0023391,21.185465 58.0023391,20.403256 C58.0023391,17.1319704 56.7063997,14.1230586 54.5623597,11.9790185 L54.4966083,11.8470949 C52.2865363,9.6877573 49.2790981,8.35652133 45.9389736,8.35652133 C45.1750795,8.35652133 44.5600908,8.97305389 44.5600908,9.73680763 C44.5600908,10.5174027 45.1751497,11.1492328 45.9389736,11.1492328 L45.9390438,11.1492328 Z M15.6971604,48.8859235 C15.6971604,45.8446622 11.0272034,45.8446622 11.0272034,48.8859235 C11.0272034,50.1971604 12.0425243,51.2431465 13.3537612,51.2431465 C14.6512444,51.2430763 15.6971604,50.1970902 15.6971604,48.8859235 Z M32.7633795,48.8859235 C32.7633795,45.8446622 28.0934225,45.8446622 28.0934225,48.8859235 C28.0934225,50.1971604 29.1409525,51.2431465 30.4199804,51.2431465 C31.7312874,51.2430763 32.7633795,50.1970902 32.7633795,48.8859235 Z M41.3026291,48.8859235 C41.3026291,45.8446622 36.6174448,45.8446622 36.6174448,48.8859235 C36.6174448,50.1971604 37.6649046,51.2431465 38.976352,51.2431465 C40.2736246,51.2430763 41.3026993,50.1970902 41.3026993,48.8859235 L41.3026291,48.8859235 Z M49.8449663,48.8859235 C49.8449663,45.8446622 45.1750094,45.8446622 45.1750094,48.8859235 C45.1750094,50.1971604 46.2225393,51.2431465 47.5015672,51.2431465 C48.7975065,51.2430763 49.8449663,50.1970902 49.8449663,48.8859235 Z M56.1911957,42.7359656 L4.71332335,42.7359656 L4.71332335,55.0816336 L56.1911957,55.0816336 L56.1911957,42.7359656 L56.1911957,42.7359656 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 32</title>
<g id="登陆和概览" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理平台-HOME2【默认】" transform="translate(-1165.000000, -1084.000000)" fill="#38B4FF" fill-rule="nonzero">
<g id="编组-39" transform="translate(1165.000000, 1084.000000)">
<g id="编组-32">
<g id="anquanzu">
<path d="M54.4157143,29.7942857 C53.7110583,37.8905447 49.266268,45.1933795 42.3985714,49.5385714 L30.21,55.89 L17.97,49.6285714 C11.0528572,45.2485714 6.50142855,37.8385714 5.80285717,29.7942857 L4.12714283,11.2157143 C4.83428566,11.2542857 5.52857139,11.2757143 6.21857145,11.2757143 C17.7642857,11.2757143 27.51,5.91857145 29.9914286,4.27714283 C32.7,5.91857139 42.4328571,11.2757143 53.97,11.2757143 C54.7242857,11.2757143 55.4742857,11.2414286 56.0357143,10.9885714 L56.1128572,10.9885714 L54.4157143,29.7942857 Z M59.9528572,7.31142855 L59.9742857,7.09714283 L57.9257143,7.34571428 C56.6404122,7.50443044 55.346492,7.58315345 54.0514286,7.58142855 C41.7385714,7.58142855 31.2771428,0.702857168 31.1742857,0.634285723 L29.9871428,0 L29.0442857,0.634285723 C28.9414286,0.702857168 18.4842857,7.58142855 6.16714283,7.58142855 C4.89428566,7.58142855 3.59571428,7.50857139 2.28857145,7.34571428 L0.402857168,7.32857145 L0.218571445,7.30714283 L0.218571445,7.32857145 L0,7.32428572 L2.05714283,30.12 C2.89714283,39.4114286 7.99714283,47.6785714 16.0757143,52.8085714 L30.1071428,60 L44.2928572,52.7185714 C52.1742857,47.7385714 57.36,39.2871429 58.1614286,30.12 L59.6485714,11.2114286 L60,7.30714283 L59.9528572,7.31142855 Z" id="形状"></path>
<path d="M43.4485714,17.2071428 L42.9642857,17.1428419 C42.4675936,17.14086 41.9901707,17.3349093 41.6357143,17.6828572 L24.3685714,34.9157143 L24.3,34.9842857 L16.0671428,26.91 C15.5295758,26.3849172 14.7320073,26.2281807 14.0357147,26.5107881 C13.3394221,26.7933956 12.8766975,27.4616528 12.8571428,28.2128572 C12.8571428,28.7057143 13.0542857,29.1685714 13.41,29.5157143 L22.8214286,38.7428572 C23.1685714,39.0857143 23.6485714,39.2828572 24.1414286,39.2828572 L24.1585714,39.0728572 L24.1585714,39.2828572 C24.6508131,39.2814823 25.1230048,39.0876838 25.4742857,38.7428572 L44.2928572,20.2928572 C44.7678944,19.8282189 44.953738,19.1425884 44.7783715,18.5016549 C44.603005,17.8607214 44.0939885,17.3652124 43.4485714,17.2071428" id="路径"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="63px" height="60px" viewBox="0 0 63 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 38</title>
<g id="登陆和概览" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-38" fill="#5B8FF9" fill-rule="nonzero">
<g id="编组-35">
<path d="M60.5578564,41.3688213 L52.5659291,4.70758644 C52.2905568,3.37119083 51.5670721,2.17837758 50.5232752,1.33985154 C49.509414,0.487303948 48.2459494,0.0150040132 46.9389957,0 L15.5844333,0 C14.2795277,0.0137684986 13.0175144,0.483434966 12.0036575,1.33260908 C10.9636635,2.17623132 10.2412217,3.36860579 9.96100355,4.70396523 L1.93403942,41.4050335 L0.21372537,50.3349629 C0.0700738975,51.1135252 0,51.8920876 0,52.6308166 L0,53.0762267 C0,53.6302734 0.0700738975,54.1481079 0.175184744,54.6695636 C0.42745074,55.9261271 0.931982791,57.0740539 1.61169947,57.9648742 C2.64879305,59.2974833 4.12034478,60 5.6970073,60 L56.7598515,60 C58.371551,60 59.8045621,59.261271 60.8451593,57.9648742 C61.4512985,57.1863118 61.9172898,56.2266884 62.1695558,55.1511859 C62.6355472,53.7425312 62.6705842,52.0731486 62.3097036,50.3711751 L60.5578564,41.3688213 Z M5.9843103,56.7734927 C4.72998768,56.6612348 3.72442731,55.6255658 3.72442731,54.3653812 L3.72442731,47.148289 C3.73542471,46.2789034 4.20236479,45.4842728 4.94371299,45.0733297 C5.33752564,44.8466322 5.78237193,44.7316902 6.23307256,44.7401775 L56.4024746,44.7401775 C56.8421165,44.7312612 57.2757856,44.8464452 57.6567973,45.0733297 C58.4266684,45.4762534 58.9116924,46.2926054 58.9111204,47.1845012 L58.9111204,54.4052146 C58.9111204,55.6653992 57.9090633,56.7010683 56.6547406,56.8133261 C56.6197037,56.7771139 5.98781398,56.7771139 5.98781398,56.7771139 L5.9843103,56.7734927 Z M13.0792917,4.5554952 C13.1844025,4.03403949 13.8290823,3.51620499 14.3686513,3.51620499 L47.8359415,3.51620499 C48.3720068,3.51620499 49.0201902,4.03403949 49.1253011,4.551874 L57.0086138,41.3652001 L5.19597899,41.3652001 L13.0792917,4.551874 L13.0792917,4.5554952 Z" id="形状"></path>
<path d="M47.2340426,49.1489362 C47.2340426,50.9115471 48.662921,52.3404255 50.4255319,52.3404255 C52.1881428,52.3404255 53.6170213,50.9115471 53.6170213,49.1489362 C53.6170213,47.3863253 52.1881428,45.9574468 50.4255319,45.9574468 C48.662921,45.9574468 47.2340426,47.3863253 47.2340426,49.1489362 L47.2340426,49.1489362 Z" id="路径"></path>
<path d="M39.6209547,31.9148453 L20.4598729,31.9148453 C18.1671854,31.9148453 16.0486548,30.7820441 14.902311,28.9432358 C13.7559672,27.1044275 13.7559672,24.8389222 14.902311,23.0001139 C16.0486548,21.1613056 18.1671854,20.028553 20.4598729,20.028553 C20.7464852,20.028553 21.0330976,20.060923 21.3197099,20.060923 C21.2494363,19.6345756 21.2143818,19.203885 21.2148517,18.7725992 C21.2282844,14.7553424 24.7414228,11.5018019 29.079214,11.4893617 C33.2595594,11.4893617 36.6919167,14.5321365 36.9051282,18.342079 C39.748941,17.3200513 42.9771577,17.9752409 45.0987953,20.0050422 C47.2204328,22.0348435 47.8225951,25.0442328 46.6271677,27.6432947 C45.4317404,30.2423565 42.6713678,31.9252824 39.6209547,31.9148453 L39.6209547,31.9148453 Z M20.6416271,21.3880907 C17.9607533,21.3880907 15.7797036,23.4047383 15.7797036,25.887513 C15.7797036,28.4058947 17.9607534,30.4257792 20.6381318,30.4257792 L39.4077431,30.4257792 C42.7317469,30.4257792 45.4475733,27.9073975 45.4475733,24.8290158 C45.4430404,22.8300013 44.2843073,20.9859198 42.4098768,19.9946326 C40.5354463,19.0033454 38.231662,19.0162844 36.3703516,20.028553 C36.118692,20.1612698 35.8320797,20.1612698 35.6188681,19.9961831 C35.3788734,19.8710665 35.2500447,19.6194799 35.2973031,19.3682062 C35.3322558,19.2031195 35.3322558,19.0024258 35.3322558,18.8049692 C35.3369143,17.2669279 34.6792414,15.7906374 33.5049018,14.7030737 C32.3305621,13.61551 30.7364793,13.0064348 29.0757187,13.0107264 C27.0319138,13.013098 25.1162557,13.9332055 23.9368089,15.479013 C22.7573621,17.0248205 22.4606098,19.0043439 23.1407466,20.7892467 C23.2491001,21.0223103 23.1756993,21.2877439 22.9659831,21.4852006 C22.7842289,21.6502873 22.4976166,21.7182642 22.2144995,21.6502873 C21.7101738,21.4805164 21.178221,21.3918403 20.6416271,21.3880907 L20.6416271,21.3880907 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

12
src/asset/image/arch.svg Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="65px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 65 65" version="1.1" height="65px">
<defs>
<linearGradient id="lg" y1="26.924%" x2="28.129%" x1="54.638%" y2="79.519%">
<stop stop-color="#fff" stop-opacity="0" offset="0"/>
<stop stop-color="#fff" stop-opacity=".27451" offset="1"/>
</linearGradient>
</defs>
<path d="m32.253 0.20991c-2.849 6.9843-4.579 11.559-7.75 18.336 1.944 2.061 4.334 4.453 8.211 7.164-4.168-1.715-7.009-3.432-9.133-5.219-4.059 8.47-10.423 20.531-23.328 43.719 10.14-5.854 18.002-9.466 25.328-10.844-0.314-1.351-0.481-2.819-0.469-4.344l0.008-0.32c0.161-6.498 3.542-11.495 7.547-11.156 4.004 0.339 7.122 5.884 6.961 12.383-0.031 1.224-0.173 2.4-0.414 3.492 7.247 1.418 15.034 5.013 25.039 10.789-1.973-3.632-3.74-6.905-5.422-10.024-2.649-2.053-5.411-4.724-11.047-7.617 3.874 1.007 6.65 2.171 8.812 3.469-17.098-31.835-18.48-36.068-24.343-49.828v-0.00009z" fill="#1793D1"/>
<path id="path2522" fill-opacity=".16568" fill="#fff" d="m50.266 38.249c-13.872-18.827-17.087-34.002-17.902-37.625 7.4 17.067 7.349 17.277 17.902 37.625z"/>
<path d="m32.378 0.45992c-0.36 0.88448-0.7 1.7468-1.032 2.5625-0.364 0.8946-0.718 1.7565-1.062 2.5938s-0.693 1.6309-1.031 2.4375c-0.339 0.8065-0.654 1.6039-1 2.4063-0.346 0.802-0.726 1.613-1.094 2.437-0.368 0.825-0.752 1.658-1.156 2.532-0.404 0.873-0.828 1.801-1.282 2.75-0.061 0.128-0.124 0.276-0.187 0.406 1.939 2.054 4.33 4.427 8.187 7.125-4.167-1.715-7-3.432-9.125-5.219-0.11 0.226-0.198 0.425-0.312 0.656-0.42 0.871-0.871 1.733-1.344 2.688-0.113 0.224-0.196 0.427-0.312 0.656-0.501 1.004-1.026 2.043-1.594 3.156-0.113 0.22-0.228 0.402-0.344 0.625-0.343 0.667-1.44 2.77-2.562 4.907-0.655 1.248-1.169 2.27-1.907 3.656-0.209 0.398-0.639 1.195-0.75 1.406 8.125-4.573 16.891-11.216 32.813-5.531-0.797-1.51-1.562-2.919-2.25-4.25-0.688-1.332-1.312-2.571-1.906-3.75s-1.143-2.291-1.657-3.344c-0.513-1.053-0.989-2.047-1.437-3s-0.885-1.87-1.281-2.75c-0.397-0.879-0.766-1.73-1.125-2.562-0.359-0.833-0.695-1.658-1.032-2.469-0.336-0.8115-0.672-1.5896-1-2.4063-0.142-0.3554-0.263-0.7338-0.406-1.0938-0.888-2.0849-1.759-4.1515-2.812-6.625v0.00002z" fill="url(#lg)"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M172.8 172.8h160l-70.4 70.4L473.6 448v19.2h-19.2L243.2 262.4l-70.4 70.4z" fill="#ADD43B" /><path d="M697.6 172.8h153.6v153.6L780.8 256 569.6 467.2h-19.2V448l211.2-211.2z" fill="#A73A8A" /><path d="M556.8 550.4H576l204.8 211.2 70.4-70.4v153.6H697.6l64-64-204.8-211.2z" fill="#F5B52E" /><path d="M454.4 550.4h19.2v19.2L262.4 780.8l64 70.4H172.8V697.6l70.4 70.4z" fill="#34378B" /><path d="M172.8 377.6l70.4-76.8L416 473.6H172.8z" fill="#ADD43B" /><path d="M416 550.4L243.2 723.2l-70.4-70.4V550.4z" fill="#34378B" /><path d="M32 518.4l108.8-115.2v96h300.8l12.8 12.8-12.8 12.8H140.8v96z m582.4-44.8l172.8-172.8 70.4 70.4v102.4z" fill="#A73A8A" /><path d="M851.2 646.4l-70.4 76.8-166.4-172.8h236.8z" fill="#F5B52E" /><path d="M576 512l6.4-12.8h300.8v-96L992 512 883.2 620.8v-96H582.4z" fill="#34378B" /><path d="M556.8 608l166.4 172.8-70.4 64h-96z" fill="#F5B52E" /><path d="M499.2 582.4l12.8-12.8 12.8 12.8v294.4h96L512 985.6 396.8 870.4h102.4v-288z" fill="#ADD43B" /><path d="M300.8 780.8L473.6 608v236.8H371.2z" fill="#34378B" /><path d="M556.8 416l166.4-172.8-70.4-64h-96z" fill="#A73A8A" /><path d="M499.2 441.6l12.8 12.8 12.8-12.8V147.2h96L512 32 396.8 147.2h102.4v294.4z" fill="#F5B52E" /><path d="M300.8 243.2L473.6 416V179.2H371.2l-70.4 64z" fill="#ADD43B" /></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More